devclub.eu quiz

топ 100 блогов lafy — 06.06.2010 На devclub.eu куча решений к quiz-у, который предложил Андрей Солнцев.

Задание: Напечатать на экране следующее:
1
2-1
1-2-3
4-3-2-1
1-2-3-4-5
6-5-4-3-2-1
(Естественно, вместо 6 может быть любое число).


Большинство решений вообщем-то похожи, разница лишь в синтаксисе (и функциях, которые доступны в языке). Все решения стремятся к "one-line solution" ну и благодаря своей динамичности и хорошей библиотеке пока большинством признано решение на Groovy (Сергей Кирьянов):
for ( i in 1..10 ) println( ( i%2 ? 1..i : i..1 ).join('-') );


С моей же точки зрения, если взять за основу, что мы выводим текст на консоль и N не может быть слишком большим, то совершенно гениальным решением является код от Ильи Хямяляйнена (который он кстати сам считает WTF-кодом):
System.out.print("1");
System.out.print("2-1");
System.out.print("1-2-3");
System.out.print("4-3-2-1");
System.out.print("1-2-3-4-5");
System.out.print("6-5-4-3-2-1");


Впрочем, на джаве это действительно выглядит ужастно, хоть и читаемо лучше всех решений :) К счастью, у нас есть Clojure, который умеет генерить такого рода штуковины.

Итак, задача сведется к тому, чтобы выводить на экран ряды из цифр, перевернутные через раз. Цифры печатаются через знак "-". Т.е. код может выглядеть так:
(do 
    (println (str-join "-" (range 1 2))) 
    (println (str-join "-" (reverse-range 1 3)))
    (println (str-join "-" (range 1 4)))
    (println (str-join "-" (reverse-range 1 5))) 
    (println (str-join "-" (range 1 6))) 
    (println (str-join "-" (reverse-range 1 7))))


Сделаем это через макросы:
(ns foo
  (:use clojure.contrib.str-utils))
  
(defn reverse-range 
    [start end]
    (reverse (range start end)))

(defmacro ranger
[size]
(let [func (cycle [`range `reverse-range])] 
    (cons 'do 
        (for [step (range 2 (+ 2 size))] 
            `(println (str-join "-" (~(nth func step) 1 ~step)))))))


Выглядит страшнее, чем код на груви, но читабельность, как ни странно, сохранена - любой программист сможет всегда вызывать macroexpand и понять, как работает тот или иной макрос:
foo> (macroexpand
      '(ranger 3))
(do (clojure.core/println (clojure.contrib.str-utils/str-join "-" (clojure.core/range 1 2))) 
    (clojure.core/println (clojure.contrib.str-utils/str-join "-" (foo/reverse-range 1 3))) 
    (clojure.core/println (clojure.contrib.str-utils/str-join "-" (clojure.core/range 1 4))))


Ну и, собственно, демка (все работает:) ):
foo> (ranger 6)
1
2-1
1-2-3
4-3-2-1
1-2-3-4-5
6-5-4-3-2-1

Оставить комментарий

Архив записей в блогах:
Пользователи жалуются на новый обман в популярном интернет-магазине. Жертвы видят сотни странных заказов в профиле, а после теряют на возврате десятки тысяч рублей. Что случилось: ...
Довелось мне в пятницу съездить по делам в Калугу. В прошлый раз я был там семь лет назад, когда только начинали строить первый автомобильный завод на окраине города. Сегодня там собирают свои машины три автогиганта, работают фабрики комплектующих, созданы тысячи рабочих мест. ...
Даша смотрела ночью по телевизору новости мира науки. Британские ученые, говорят, выяснили, как общаются овощи. Не вполне понятно, между собой они общаются, или с британскими учеными, и в целом совершенно неясно, зачем они это делают, но вот вам факт. Овощи, оказывается, это умеют. А я ...
В середине 1970-х годов, с потерей Испанией и Португалией последних владений в Африке, на повестке дня нарисовался и вопрос будущего их островных территорий в Атлантике – в самом деле, чем они хуже Кабо-Верде, отправленного в независимость вопреки мнению подавляющего большинства его ...
Надеюсь, что пишу именно в то сообщество, поскольку еду в Минск. Какую валюту лучше с собой везти (доллары, рубли, евро)? Какой сейчас нормальный курс у менял? Знакомые говорят что рубль по 290 меняют. Что посмотреть? Что прикупить? Как дела? ...