您自己的“ for”指令


38

您自己的“ for”指令

假设您有以下输入: 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是一个字符串或一个char,它不能是别的,for循环结束条件中使用的比较器 。

    b可以并且必须是以下字符串之一:

    - ">"
    - "<"
    
  • c是一个整数,在for 循环结束条件中使用的数字。

  • d是在每个循环中加到i 的整数

这是代码高尔夫球,答案最短!


1
数字可以作为列表/序列从函数中返回,而不是打印到stdout吗?
smss

@smls不,抱歉,输出必须像示例一样!
Sygmei

1
它说我的代码应该跟随伪代码,并且有一个print "\n",但是我在每行使用javascript的警报。这是可以接受的,还是我必须使用console.log来延长回答时间?

2
您可以将警报功能用作输出的一种方法,但不能使用多个警报。喜欢的东西alert("23\n24\n25");会工作,而alert("23"); alert("24"); alert(25);不会
Sygmei

Answers:


25

JavaScript(ES6), 44  43 56字节

ETHproductions节省了1个字节
编辑:固定为符合输出要求

(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逐行输出。
乔伊(Joey)

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)

非常感谢Arnauld出色的高尔夫运动。

alertconsole.log由于输出规格而更改为


@Arnauld谢谢,那是一个非常酷的高尔夫。我只是问他,所以让我们看看他是否接受。

很高兴看到它被接受。;)
Arnauld

这不符合规范,在规范中,每行之后以U + 000A逐行输出。
乔伊(Joey)

@Joey这只是伪代码,但是我会问OP这件事。

@Masterzagh:关于替代输出格式的问题已经被拒绝。
乔伊(Joey)


13

果冻,12字节

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

在线尝试!

Jelly有很多方法可以简洁地执行迭代,创建范围等。但是,由于特殊情况(例如,增量为0,循环在它开始之前结束(由于不等式向后),)精确地镜像C ++的行为是相当困难的。 ),并且增量的方向错误(因此自然无法满足循环的退出条件)。因此,该解决方案基本上是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之类的语言要容易得多)。该程序的十六进制转储长度为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

05AB1E22 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怎么样?
17Me21年

@ 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 Walters

不必i从头开始a,不是0吗?您可以完全使用a和跳过,i并使用ASCII值“>”。for(;b==62?a>c:a<c;a+=d)
莱利

不适用于f(1,'<'3,1);
RomanGräf17年

嗯...是的,需要双方都算数;for(b-=61;b*a>b*c;a+=d)为单个字节工作;但是也是for(;b-62?a<c:a>c;a+=d)
H Walters



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

谢谢。删除第三个e()之后的\ n \ t之后,尺寸仍然相同
G-Ox7cd


3

Bash(+ Unix工具),29字节

打高尔夫球

bc<<<"for(x=$1;x$2$3;x+=$4)x"

测试

./forloop 1 '<' 10 1
1
2
3
4
5
6
7
8
9

1
哈。我正要发布完全相同的内容!+1
数字创伤


3

dc,47个字节

dc,48个字节

还有Bash + Unix实用程序,29字节

直流电(47字节):

1sb[_1sb]s zz?sdlb*sc[pld+lnx]sl[dlb*lcr<l]dsnx

在线尝试!

请注意,负数必须用下划线而不是负号输入,因为这是dc接受数字输入的方式。因此,例如,写_5而不是-5。


dc无法读取输入到变量中的字符或字符串并对其进行处理(下面有更详细的说明),但是我发现了解决此问题的两种方法:

47个字节的DC解决方案适用于具有参数1和参数2逆转,用空格作为分隔符输入。因此,从1到(但不包括)10的步长为3的计数将输入为:

< 1 10 3

如果不能改变参数的顺序,我还提供了一个48字节的dc解决方案,该解决方案保留了参数的原始顺序。这zz用作参数之间的分隔符。因此,以3的步数从1向上计数(但不包括10)将再次使用以下输入行:

1zz<zz10zz3

最后,相同的想法产生了一个29字节的bash解决方案


有关dc缺少字符串处理以及该程序如何处理的详细信息:

在dc中处理此问题非常棘手,因为dc不像大多数语言那样接受字符串或char输入。dc读取输入字符串时,它将立即作为dc程序(宏)运行该字符串,然后丢弃该字符串。您不能将字符串的字符存储在内存中,以后再以其他任何方式对其进行处理。这会干扰输入中必须包含“ <”或“>”的要求。

我将展示两种解决方法。在上述解决方案(47字节)中,我们切换了前两个输入的顺序。输入定界符是空格字符。例如,要以3的步长从1到(但不包括)10进行计数,您需要输入

< 1 10 3

这是此解决方案背后的想法:

dc中的宏存储在寄存器中,并且寄存器具有单字符名称。我将宏存储在寄存器中,其名称只是一个空格字符。

该程序通过在获取输入之前在堆栈上压入0和1来工作。然后,当输入作为dc程序运行时(这是dc在输入行中所做的事情),'<'或'>'字符作为命令执行,这是名称为“ <”或“>”之后的下一个字符。具体来说,将弹出堆栈中的前两项。如果弹出的第一项是<(分别是>)第二个弹出的项,则执行指示的宏。下一个字符(在'<'或'>'之后)是一个空格,因此,如果条件成立,我们存储在名称为空格char的寄存器中的宏就是要执行的宏。但是我们将0和1压入堆栈,所以弹出的第一项是1,弹出的第二项是0。结果,仅当条件测试为>而不是<时,才执行宏。这使我们可以区分输入中的“ <”和“>”。

该行中的其余项目只是数字,而dc只会将这些数字依次推入堆栈。

这是详细说明。大多数情况下,计数变量(问题语句伪代码中的i)存储在堆栈的顶部。

1sb             Store 1 in register b.  (b will end up being 1 for '<', and -1 for '>').
[_1sb]s         Note that there is a space after the second s.  So the space char is the name of a macro which stores -1 in b.
z               Push 0 on the stack.
z               Push 1 on the stack.
?               Accept input in the format above.  This will:
                    - Store 1 or -1 in b, depending on whether you've typed "<" or ">"
                    - Push each of the three numbers in turn on the stack.
sd              Save the increment in register d.
lb*sc           Save either limit or -limit in register c, depending on whether the input started with "<" or ">".
[pld+lnx]sl     Define a macro called l which is the body of our loop:
                    - Prints the top of the stack
                    - Adds the increment to the top of the stack.
                    - Calls macro n (the loop test).

 [dlb*lcr<l]dsn  Define a macro called n which is the test of the loop:
                    It checks to see if i (at the top of the stack) times b is less than c; if so, it calls macro l (looping back).
 x               Execute the loop test macro initially (a while loop needs to have a test at the top before entering the loop the first time).

另一方面,《任择议定书》指出:

Input can be in one-line using any format "a/b/c/d" or "a,b,c,d" etc.

因此,在输入中的a之前切换顺序并要求b是不合法的。

这是一种将a,b,c和d保持原始顺序的替代方法。我们可以使用任何定界符;我将使用zz作为分隔符。因此,从1到(但不包括)10以3的步长计数将输入为:

1zz<zz10zz3

具有zz分隔输入的新程序是

直流电(48字节):

1sb[_1sb]sz?sdiilb*sci[pld+lnx]sl[dlb*lcr<l]dsnx

这比47字节的第一个解决方案长一个字节。

在线尝试zz分隔版本!

我个人认为,不同顺序的< 1 10 3格式1zz<zz10zz3更符合问题的实质,但也许可以更好地满足实际的技术规范。

如果在不同的输入参数之间允许使用不同的分隔符,则可能会得到更短的解决方案,但是我认为这并不是问题的实质。

Bash + Unix实用程序,29字节

您可以将上面的基本思想变成一个bash程序(称为dc)。这避免了使用“ <”和“>”带来的所有麻烦,并且还简化了各种数字参数的处理,因此它只有29个字节长,与@zeppelin的bash + bc答案相同。

bash版本(29字节):

dc -e[p$4+d$3r$2l]sl$1d$3r$2l

在线尝试bash版本!

这是bash程序中dc程序工作方式的描述:

i的值大多数时候都存储在堆栈的顶部。

[      Start of macro (i is at the top of the stack). This macro will be called l.
p      Print i
$4+    i += (4th argument)
d      Duplicate i at the top of the stack.
$3     Push the 3rd argument onto the stack.
r      Swap the top two items on the stack, so i is at the top and arg3 is second
$2l    $2 is "<" or ">", causing the top two items to be popped from the stack, and macro l is then called (effectively looping back) if i < arg3 or i > arg3, respectively.
]sl    End of macro definition; store macro in register l.

$1     Push argument 1 onto the stack (i = 1st argument).
d$3r$2l Just as above, call macro l if i < arg3, or i > arg3, depending on whether arg2 is "<" or ">"

3

普通Lisp 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推迟了挑战。


整齐!我不确定在创建挑战时是否应该包括所有常见的运算符,所以我记得它们并不完全相同(例如Lua中的〜=代表!=)
Sygmei

哇,评估是邪恶的。
cyberbit

在我看来,您可以使用PHP 7.1使其更短。如果不是这样的使用list节省了4个字节加上短语法4个字节
约尔格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.

如果可以返回一个(可能是无限的)数字序列作为type的值Seq,而不是将数字打印到stdout,则.say for可以删除该部分,将其减少到35个字节。


2

Clojure,66 63字节

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

通过将-3字节分解出来loop。我正在“滥用” init参数来充当正在运行的累加器。

递归解决方案(使用TCO)。请参阅预先编写的代码中的注释。我尝试了一种非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与my 结合在一起({">">"<"<}%2)
NikoNyrh

2

Groovy,51个字节

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

这是一个未命名的闭包。在线尝试!

注意 -如果要使用进行测试groovy console,请确保在输入导致无限循环时终止整个过程。在它消耗了大约5兆的RAM之后,我注意到了这一点。


2

QBIC51 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

如果该步骤具有错误的符号,则这根本不执行任何操作。额外的测试是因为Batch的for循环允许循环变量等于最终值。


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

没错,但是我认为我所了解的大多数语言都不会允许Clothre <代替"<",而是Clojure。
NikoNyrh

@Sygmei是的。虽然那会很甜蜜。不能怪你打那个电话。
Carcigenicate

OP表示比较操作符btw使用字符代替字符串是可以的。那应该节省几个字节。
Carcigenicate
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.