Ваша собственная инструкция «для»


38

Ваша собственная инструкция "для"

Предполагая, что у вас есть следующий вход: a, b, c, d

Ввод может быть в одну строку с использованием любого формата «a / b / c / d» или «a, b, c, d» и т. Д.

Вы также можете иметь 4 входа.

Вы должны кодировать следующее поведение (псевдокод здесь):

var i = <a>
while (i <b> <c>)
    print i
    i = i + <d>
    print "\n"

Вот несколько тестов:

input : 1,<,10,1
output :
1
2
3
4
5
6
7
8
9

Еще :

input : 20,>,10,1
output :
20
21
22
23
24
25
26
27
...
infinite loop / program crashes
  • aявляется целым числом , начальное значение i.

  • bэто строка или символ , это не может быть что-то еще, компаратор, используемый в конечном состоянии forцикла.

    bможет и должен быть одной из следующих строк:

    - ">"
    - "<"
    
  • cявляется целым числом , числом, используемым в конечном состоянии for цикла.

  • dпредставляет собой целое число , которое добавляется к I в каждом цикле.

Это код-гольф, самый короткий ответ выигрывает!


1
Могут ли числа возвращаться из функции в виде списка / последовательности, а не выводиться на стандартный вывод?
— Смс

@smls Нет, извините, вывод должен быть как в примерах!
— Сигмей

1
Там написано, что мой код должен следовать псевдокоду print "\n", но есть , но я использую предупреждение javascript для каждой строки. Будет ли это приемлемым, или мне придется вместо этого использовать console.log, чтобы сделать ответ дольше?

2
Вы можете использовать функцию оповещения как способ выхода, но вы не можете использовать несколько оповещений. Нечто подобное alert("23\n24\n25");сработало бы, тогда как не сработало alert("23"); alert("24"); alert(25);бы
— Сигмей

Ответы:


25

JavaScript (ES6),  44  43 56 байт

Сохранено 1 байт благодаря ETHproductions
Edit: исправлено для соответствия требованиям вывода

(a,b,c,d)=>{for(s='';eval(a+b+c);a+=d)s+=a+`
`;alert(s)}

Тест


Хорошее использование области!
— ETHproductions

Я думаю, что вы можете изменить порядок, evalчтобы сохранить байт:(a,b,c,d)=>{for(;eval(a+b+c);a+=d)alert(a)}
— ETHproductions

@ETHproductions Ах, да. Хороший!
— Arnauld

5
Это 44 с пачкой!
— aross

Это не соответствует спецификации, где вывод построчный с U + 000A после каждой строки.
— Джои

17

Javascript (ES6), 47 42 48 байт

Хотел сделать версию for, но кто-то был быстрее, так что вот рекурсивная версия.

(b,c,d)=>F=a=>eval(a+b+c)&&console.log(a)|F(a+d)

Вы должны добавить f=раньше и назвать его как f(b,c,d)(a).

Большое спасибо Арно за потрясающий гольф.

alertизменено на console.logиз-за выходной спецификации


@Arnauld Спасибо, это очень крутой гольф. Я просто спросил его, так что давайте посмотрим, принимает ли он это.

Рад, что это принято. ;)
— Arnauld

Это не соответствует спецификации, где вывод построчный с U + 000A после каждой строки.
— Джои

@Joey Это просто псевдокод, но я спрошу у ОП об этом.

@Masterzagh: Был вопрос об альтернативных форматах вывода, который был отклонен.
— Джои


13

Желе , 12 байт

Ṅ+⁶µ⁴;⁵¹vµ¿t

Попробуйте онлайн!

У Jelly есть много способов кратко выполнять итерации, создавать диапазоны и т. Д. Однако точно отразить поведение C ++ довольно сложно, поскольку в особых случаях, таких как приращение равно 0, цикл заканчивается до его начала (из-за неравенства в обратном направлении). ), и приращение идет в неправильном направлении (что означает, что условие выхода цикла не может быть выполнено естественным образом). Таким образом, это решение в основном является прямым переводом C ++, хотя это делает его более низкоуровневым, чем обычно программа Jelly. К счастью, C ++ имеет неопределенное поведение при переполнении целых чисел со знаком (вопрос использует int), что означает, что программа может сделать что-нибудь в этом случае, и, следовательно, нет необходимости пытаться имитировать поведение переполнения.

объяснение

Ṅ+⁶µ⁴;⁵¹vµ¿t
   µ     µ¿   While loop; while ((⁴;⁵¹v) counter) do (counter = (Ṅ+⁶)counter).
    ⁴;⁵       Second input (b) appended to third input (c), e.g. "<10"
        v     Evaluate, e.g. if the counter is 5, "<10" of the counter is true
       ¹      No-op, resolves a parser ambiguity
Ṅ             Output the counter, plus a newline
 +⁶           Add the fourth input (d)
           t  Crashes the program (because the counter is not a list)

Сбой программы - самый краткий способ отключить неявный вывод Jelly (в противном случае он вывел бы конечное значение счетчика); он генерирует кучу сообщений об ошибках на stderr, но мы обычно считаем, что это разрешено.

Между прочим, счетчик цикла инициализируется текущим значением до запуска цикла. Поскольку цикл появляется в начале программы, это будет первый ввод.


Вы можете изменить, tчтобы Ḋне иметь сбоев. Результатом удаления является пустой список, для которого неявная печать Jelly ничего не дает.
— Джонатан Аллан

@JonathanAllan: Нет, на самом деле он создает диапазон от 2 до заданного значения, что определенно видно на неявном отпечатке.

Ах, я, должно быть, проверил эту теорию с циклом, заканчивающимся на отрицательной территории; действительно диапазон создается неявно.
— Джонатан Аллан

Хм, это 12 символов, но это не 12 байтов, верно?
— Cruncher

@Cruncher: Jelly использует свою собственную кодировку, в которой каждый символ, используемый языком, представлен одним байтом (он использует только 256 различных символов). Причина, по которой он не использует что-то более известное, например, кодовую страницу 437, состоит в том, чтобы упростить ввод текста (я имею в виду, что это не так просто печатать, но это проще, чем язык, подобный gs2). Hexdump этой программы будет иметь длину 12 байт.



9

Java, 58 байт

(a,b,c,d)->{for(;b>61?a>c:a<c;a+=d)System.out.println(a);}

14
Есть ли причина для создания i? Не могли бы вы пропустить часть инициализации и просто использовать a? Кроме того, использование значения ASCII '>' (62) сохраняет байт.
— Райли

6
Следуя комментарию Райли, вы можете сделатьb>61
— Kritixi Lithos

Я не верю, что это компилируется.
— ChiefTwoPencils

@ChiefTwoPencils Это функция. Вы должны написать тестовую программу, чтобы скомпилировать ее.
— wizzwizz4

@ wizzwizz4, очевидно. Но это все еще не работает. Дать ему шанс. Кроме того, я понимаю, что все байты, необходимые для запуска, имеют значение.
— ChiefTwoPencils

7

05AB1E , 22 20 байт

[D²`'>Q"‹›"è.V_#D,³+

Попробуйте онлайн!

объяснение

[                       # start loop
 D                      # copy top of stack (current value of a)
  ²`                    # push b,c to stack
    '>Q                 # compare b to ">" for equality
       "‹›"             # push this string
           è            # index into the string with this result of the equality check
            .V          # execute this command comparing a with c
              _#        # if the condition is false, exit loop (and program)
                D,      # print a copy of the top of the stack (current value of a)
                  ³+    # increment top of stack (a) by d

1
Любой формат ввода принимается, поэтому вторая версия в порядке :)
— Sygmei

7

SmileBASIC, 53 байта

INPUT A,B$,C,D
S=ASC(B$)-61WHILE S*A>S*C?A
A=A+D
WEND

Объяснение:

INPUT A,B$,C,D
IF B$=="<" THEN S=-1 ELSE S=1 'get comparison direction
I=A
WHILE S*I>S*C 'loop while I is less than/greater than the end
 PRINT I
 INC I,D
WEND

Это использует тот факт, что так X<Yже, как-X>-Y


Я верю тебе за это, у меня нет 3DS для тестирования :)
— Sygmei

У меня Petit Computer, такая классная идея! Я попробую что-нибудь подобное когда-нибудь ...
— python-b5

Вы можете использовать READоператор, сохраняя 1 байт.
— ckjbgames

@ckjbgames как?
— 12Me21

@ 12Me21 Ознакомьтесь с руководствами SmileBASIC. Должен быть в списке инструкций для SmileBASIC.
— ckjbgames

6

С накоплением , 34 байта

@d@c@b[show d+][:c b tofunc!]while

Попробуйте онлайн! (Включено тестирование.) Эта функция ожидает, что стек будет выглядеть так:

a b c d

Например:

1 '<' 10 2
@d@c@b[show d+][:c b tofunc!]while

объяснение

@d@c@b[show d+][:c b tofunc!]while
@d@c@b                               assign variables
               [............]while   while:
                :c                   duplicate "i" and push c
                   b tofunc!         convert b to a function and execute it
      [.......]                      do:
       show                          output "i" without popping
            d+                       and add the step to it

4

C ++, 80

К сожалению, это C++не так C. Был немного смущен вопросом.

void f(int a,char b,int c,int d){for(;b==62?a>c:a<c;a+=d)cout<<a<<endl;}

Это C или C ++?
— betseg

10
Какая реализация C ++? (Мне любопытно, как вы получаете что-то похожее using namespace stdбесплатно).
— H Уолтерс

Не iнужно начинать a, не 0? Вы можете просто использовать aи iвообще пропустить и использовать значение ASCII '>'. for(;b==62?a>c:a<c;a+=d)
— Райли

Не работает дляf(1,'<'3,1);
— Роман Gräf

Ack ... да, требует математики с обеих сторон; for(b-=61;b*a>b*c;a+=d)работает на один байт; но так же for(;b-62?a<c:a>c;a+=d).
— H Уолтерс



4

Пип , 14 байт

W Va.b.ca:d+Pa

Принимает четыре аргумента командной строки. Поддерживает отрицательные числа и числа с плавающей запятой и операторы сравнения < > = <= >= !=. Попробуйте онлайн!

                a,b,c,d are cmdline args
W               While loop with the following condition:
  Va.b.c          Concatenate a,b,c and eval
            Pa  Print a with newline (expression also returns value of a)
        a:d+    Add d to that and assign back to a

4

Желе , 8 байт

ḢṄ+⁹;µV¿

Это диадическая ссылка, которая принимает a, b, c в качестве левого аргумента и d качестве правого. Выход может быть бесконечным и переходит в STDOUT.

Попробуйте онлайн!

Как это работает

ḢṄ+⁹;µV¿  Dyadic link.
          Left argument:  a,b,c (integer, character, integer)
          Right argument: d     (integer)

       ¿  While...
      V     the eval atom applied to a,b,c returns 1:
     µ       Combine the links to the left into a chain and apply it to a,b,c.
Ḣ              Head; pop and yield a from a,b,c.
 Ṅ             Print a, followed by a linefeed.
  +⁹           Add a and the right argument (d) of the dyadic link.
    ;          Concatenate the result and the popped argument of the chain,
               yielding a+d,b,c.

Аргументы командной строки используют синтаксис Python и не могут отличить символ от одиночной строки. Если вы хотите использовать CLA, вы должны вставить, Fчтобы сгладить массив.
— Деннис

2
Теперь я хочу удалить половину моего комментария, так как он устарел, оставив при этом другую половину. Полагаю, я просто повторю соответствующую половину и удалю оставшуюся: «О, блин, вы определили это как функцию, чтобы вы могли игнорировать неявный вывод в соответствии с правилами PPCG. Я должен был подумать об этом».

4

Python 2 , 45 байт

exec"i=%d\nwhile i%c%d:print i;i+=%d"%input()

Попробуйте онлайн!

Очень буквальная реализация спецификации. Принимает шаблон кода, подставляет во входные данные форматирование строки и выполняет его.


4

Простой TeX, 88 байт

\newcount\i\def\for#1 #2 #3 #4 {\i#1\loop\the\i\endgraf\advance\i#4\ifnum\i#2#3\repeat} 

Команда \forпредоставляет запрошенную функцию. Сохранить это какfor.tex а затем запустите и введите значения переменных в командной строке: pdftex '\input for \for 1 < 5 1 \bye'Значения переменных должны быть разделены пробелами.


4

Python 3, 61 байт

Один лайнер:

e=input;exec(f'i={e()}\nwhile i{e()}{e()}:print(i);i+={e()}')

Добро пожаловать на сайт! Хорошее использование новой функции интерполяции литеральных строк. Я думаю, что вы могли бы сохранить байт, заменив \tего пробелом.
— 0

Спасибо. Тот же самый размер после удаления \ n \ t после третьего e ()
— G-Ox7cd




3

Обыкновенный Лисп, 82 80 79 73 64 байта

(defmacro f(a b c d)`(do((i,a(+ i,d)))((not(,b i,c)))(print i)))

Тест

(f 1 < 10 1)

1 
2 
3 
4 
5 
6 
7 
8 
9 
NIL
CL-USER> 

-9 байт благодаря PrzemysławP.


Возможно, вы можете сохранить 9 байтов, определив макрос. (defmacro f(a b c d)<insert backqoute here>(do((i,a(+ i,d)))((not(,b i,c)))(print i)))Использование:(f 1 < 10 1)

@ PrzemysławP Еще раз спасибо!
— coredump

3

PHP, 69 65 байт

for(list(,$i,$b,$c,$d)=$argv);$b<"="?$i<$c:$i>$c;$i+=$d)echo"$i
";

Запустите с '-r'; предоставить аргументы командной строки в качестве входных данных.

Для одного байта больше больше 4 байта, я могу взять каждый оператор:

for(list(,$i,$b,$c,$d)=$argv;eval("return $i$b$c;");$i+=$d)echo"$i
";

Да, злой Эвал. Знаете ли вы, что он может что-то вернуть?


Сокращение структуры [,$i,$b,$c,$d]=$argv;сократит еще 4 байта;
но PHP 7.1 откладывает вызов.


Аккуратно! Я не был уверен, создавая задачу, нужно ли мне включать все общие операторы, тогда я вспомнил, что они не все одинаковы (~ = for! = В Lua, например)
— Sygmei

Вау, Эваль это зло.
— cyberbit

Мне кажется, что вы можете использовать PHP 7.1, чтобы сделать его короче. Если это не так, использование listсохраняет 4 байта плюс 4 байта с коротким синтаксисом
— Jörg Hülsermann

@PHP 7.1 постдатует вызов; но спасибо за list().
— Титус

2

Perl 6 , 44 байта

{.say for $^a,*+$^d...^*cmp$^c!= $^b.ord-61}

Как это работает

{                                          }  # A lambda.
          $^a                                 # Argument a.
             ,*+$^d                           # Iteratively add d,
                   ...^                       # until (but not including the endpoint)
                       *cmp$^c                # the current value compared to c
                                              # (less=-1, same=0, more=1)
                              != $^b.ord-61.  # isn't the codepoint of the b minus 61.
 .say for                                     # Print each number followed by a newline.

Если можно вернуть (потенциально бесконечную) последовательность чисел в качестве значения типа Seq, вместо .say forвывода чисел на стандартный вывод, часть можно удалить, уменьшив ее до 35 байт.


2

Clojure, 66 63 байта

#(when((if(= %2"<")< >)% %3)(println %)(recur(+ % %4)%2 %3 %4))

-3 байта с учетом loop. Я "злоупотребляю" параметром init, чтобы действовать как работающий аккумулятор.

Рекурсивное решение (с TCO). Смотрите комментарии в коде pregolfed. Я попробовал рекурсивное решение без TCO, и оно оказалось 67 байтами.

Я хотел бы видеть этот удар в Clojure! Я думаю, что это самое маленькое, что я могу получить.

(defn my-for [init-num com-str com-num inc-num]
  (let [op (if (= com-str "<") < >)] ; Figure out which operator to use
    (when (op init-num com-num) ; When the condition is true, print and recur
      (println init-num)
      (recur (+ init-num inc-num) com-str com-num inc-num))))
    ; Else, terminate (implicit) 

О, я не заметил этот ответ. #(when(({">">"<"<}%2)% %3)(println %)(recur(+ % %4)%2 %3 %4))будет 61 байт, сочетая ваш whenс моим ({">">"<"<}%2).
— NikoNyrh

2

Groovy, 51 байт

{a,b,c,d->while(Eval.me("$a$b$c")){println a;a+=d}}

Это безымянное закрытие. Попробуйте онлайн!

Внимание - Если вы хотите проверить это с помощью groovy console, убедитесь, что вы уничтожили весь процесс, когда ввод вызывает бесконечный цикл. Я заметил это после того, как он потребил ~ 5 гигабайт оперативной памяти.


2

QBIC , 51 40 байт

:;::{?a┘a=a+c~A=@<`|~a>=b|_X]\~a<=b|_X

И через три минуты после публикации я понял, что могу упростить логику терминатора ...

:;::      Consecutively read a, A$, b and c from the command line
{?a┘      Start an infinite loop; print a, add a newline to the source
a=a+c     increment a
~A=@<`|   If we are in LESS THAN mode
  ~a>=b   and IF we are no longer LESS
    |_X]  THEN QUIT, end if.
  \       ELSE (we're in GREATER THAN mode)
    ~a<=b IF we are no longer GREATER
    |_X   THEN QUIT
          The last IF and the loop are auto-closed

2

Пакет, 94 байта

@set i=%1
@set o=gtr
@if "%~2"=="<" set o=lss
:g
@if %i% %o% %3 echo %i%&set/ai+=%4&goto g

Если бы не поведение второго параметра, это можно сделать за 53 байта:

@for /l %%i in (%1,%4,%n%)do @if not %%i==%3 echo %%i

Это просто ничего не делает, если шаг имеет неправильный знак. Дополнительный тест заключается в том, что forцикл Batch позволяет переменной цикла равняться конечному значению.


2

Clojure, 66 байт

#(loop[i %](if(({">">"<"<}%2)i %3)(do(println i)(recur(+ i %4)))))

Это могло быть 55 байтов, поскольку <и >являются функциями в Clojure:

(def f #(loop[i %](if(%2 i %3)(do(println i)(recur(+ i %4))))))
(f 1 < 10 1)

Мне нравится использование карты здесь. Я бы никогда не подумал, что это побило бы меня. Также интересно, что оба наших начальных подсчета были одинаковыми, несмотря на немного разные подходы.
— Carcigenicate

Разрешение b быть функцией дало бы несправедливое преимущество некоторым языкам :)
— Sygmei

Правда, но я думаю , что большинство языков я знаю, не пойдут на пользу много от разрешения <вместо "<", за исключением Clojure.
— NikoNyrh

@Sygmei Правда. Это было бы чертовски мило, хотя. Не могу винить тебя за этот звонок.
— Carcigenicate

OP сказал, что символы хороши вместо строк для операторов сравнения. Это должно сэкономить пару байтов.
— Carcigenicate

2

TI-Basic, 41 34 байта

Prompt A,Str2,Str3,D
While expr("A"+Str2+Str3
Disp A
A+D->A
End

1
Как работает калькулятор TI, многие символы хранятся в виде одного байта. Prompt , Str2, Str3,While , expr(, Disp , ->, И Endвсе символы однобайтные. Я считаю 29 байтов.
— Павел

@Pavel Спасибо за ваш интерес! Несмотря на то, что TI-Basic является токенизированным, не все токены являются одним байтом. Так , например, Str2, Str3, и expr(все два байта маркеры. Чтобы увидеть список однобайтовых токенов, посмотрите tibasicdev.wikidot.com/one-byte-tokens
— Timtech
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.