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


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.