重塑For循环[关闭]


23

For 循环在许多语言中广泛使用,但是如果没有语言支持,您将怎么办?

创建的方式来执行基本for循环,而无需使用任何重复结构(forforeachwhiledo,等等)。

像这样设置您需要复制的基本for循环

for(i=0;i<1000;i++)

您必须能够在不使用重复结构的情况下复制它。它还必须以您的语言执行将在循环体内的代码。eval允许使用任何形式,尽管它可能无法自行执行for循环。

您可以通过将代码打印i100次来测试您的代码,将此测试用例添加到答案的末尾以与他人验证您的代码。

对于它到底是什么没有任何限制,它要做的就是复制for循环。

优胜者将根据其选择时的投票决定。


100次还是1000次?还是十万次?
用户未知,

10
我觉得这个问题太不确定了。您说“不使用任何重复结构”,仅给出此类禁止结构的示例(但不能提供详尽的列表)。到目前为止,提供的答案使用递归或goto,将它们都归类为“重复结构”,但可以争论。如果没有正确定义允许什么和不允许什么,这个问题就不会引起兴趣。
Timwi

gotos,递归...
Mateen Ulhaq 2011年

我投票关闭这是题外话,因为我们需要针对所有挑战的客观有效性标准。就目前而言,没有明确的方法来确定提交的有效性。此外,没有规定有效提交的行为。
Mego

Answers:


23

C,如果没有,则不带goto的45个字符。

不是最小的解决方案,但是我发现在C中用这种方法很有趣:)

不使用gotoiffor,或任何其他类型的控制结构。

本身的功能(45个字符):

m(){int (*a[])()={m,exit};i++;(*a[i>999])();}

一个可编译的工作程序:

#include <stdio.h>
#include <stdlib.h>

int i=0;
m(){int (*a[])()={m,exit};i++;printf("%i ",i);(*a[i>999])();}

int main()
{
  m();
}

2
函数调用是“控制结构”。对?
EfForEffort,2012年

@Denis布埃诺:没有,控制结构是这样的东西whiledoforif...
houbysoft

1
能否请您说明一下?我有点迷路了。
Rees 2014年

1
这有点晚了,但是@Rees:int (*a[])()={m,exit}是一个函数指针数组。m被称为递增和打印i(设置为1、2、3,...),并从函数指针数组中调用一个函数。调用(*a[i>999])();将扩展为(*a[0])();或,(*a[1])();因为C将i>999根据真或假(1或0)将值用作整数。它将m一直调用到i>999true,然后调用exit。很好地使用函数指针。
aglasser 2014年


12

GCC- 106 95个字符

#define FOR(i,l,h)auto F();L(F,l,h);int F(i)
L(int f(int),int l,int h){l<=h?f(l),L(f,l+1,h):0;}

与必须声明回调的其他C解决方案不同,此解决方案可以为您自动完成:

FOR(i, 1, 10) {
    printf("%d\n", i);
}

它通过使用GCC的嵌套函数扩展来工作。即,它向前声明嵌套函数F,将其传递给循环函数L,然后开始的定义F,为用户添加括号。

GCC中的嵌套函数的一个美丽之处是它们支持向下的funarg,这意味着幻觉几乎是完整的:

long n = 1;
FOR(i, 1, 10) {
    n *= i;
}
printf("%ld\n", n); // 3628800

有一个主要警告:如果FOR在同一作用域中使用两次,则会发生冲突(即,它将编译,但所有FOR循环将共享一个循环体)。要在同一个作用域中允许多个FOR循环,我们将需要再增加69 65个字符:

175160个字符:

#define FOR(i,l,h)F(i,l,h,__COUNTER__)
#define F(i,l,h,f)auto N(f)();L(N(f),l,h);int N(f)(i)
#define N(n)F##n
L(int f(int),int l,int h){l<=h?f(l),L(f,l+1,h):0;}

11

C,21个字符

f(){if(c++<999)f();}

例如:

#include <stdio.h>
int c = 0;
f()
{
    printf("%d ", c);
    if (c++<999) f();
}
int main(void)
{
    f();
}

输出:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ... 998 999

如果main()在第一个块中没有,则代码将不会链接。因此,我认为它应该包含在条目中。
内森·奥斯曼

4
@乔治:我认为main()在这种情况下可以省略,因为这个问题说的是“创建一种执行方式”,而不是像其他问题那样“制作完整的程序”。
Eelvex 2011年

1
删除void 则将26仅是字符。
约翰·卫斯理王子

8

C#—没有递归,没有goto

(使用来自lambda演算的Y组合器)

class Program
{
    delegate Func<TInput, TResult> Lambda<TInput, TResult>(Lambda<TInput, TResult> f);

    static Func<TInput, TResult> Y<TInput, TResult>(Func<Func<TInput, TResult>, Func<TInput, TResult>> f)
    {
        Lambda<TInput, TResult> y = r => n => f(r(r))(n);
        return y(y);
    }

    static void Main()
    {
        Func<int, int> fibonacci = Y<int, int>(f => n => n > 1 ? f(n - 1) + f(n - 2) : n);
        Func<int, int> factorial = Y<int, int>(f => n => n == 0 ? 1 : n * f(n - 1));

        // Executes “fibonacci” 10 times, yielding 55
        Console.WriteLine(fibonacci(10));
        // Executes “factorial” 5 times, yielding 120
        Console.WriteLine(factorial(5));
    }
}

有人可能会说Y运算符实现了递归……
Bergi 2014年

7

x86汇编程序,价值12 11字节的指令

66 31 c0                xor    %ax,%ax
<body>                ; involving %ax
66 40                   inc    %ax
66 3d  e8 03            cmp    $1000,%ax
75 ??                   jne    <body>

可惜他们被要求升序...我敢肯定,降序会更短。
JB

@JB:是的,按降序排列,您通常会使用以下loop指令:mov cx, 1000\nx: ... loop x
Jerry Coffin

6

Scala的另一个变体

由于Scala允许使用非ASCII字符,因此我们可以为:)(o是西里尔字母)实现real 。

def fоr(s:Unit,c: ⇒Boolean,e: ⇒Unit)(b: ⇒Unit):Unit=if(c){b;e;fоr(0,c,e)(b)}

测试:

var i:Int = _

fоr (i = 0, i < 1000, i += 1) {
  print(i + " ")
}

6

JavaScript,34个字符

假设实际的打印功能不是for循环的一部分。

参数化递归(43)

function f(i,m,c){if (i<m){c();f(++i,m,c)}}

function f(i, max, callback)
{
  if (i<max)
  {
    callback();
    f(++i,max,callback);
  }
}

反向递归(36)
假定max >= 0

function f(m,c){if(m){c()
f(--m,c)}}

function f(max,callback)
{
  if(max)
  {
    callback();
    f(--max,callback);
  }
}

三元运算符(34)

function f(m,c)
{m?c()&f(--m,c):0}

3
function f(m,c){m&&c()&f(--m,c)}-您可以输入32个字节:)
pimvdb

5

Ruby 1.9-51个字符

def f a,b,c,&d
a[]
k=->{d[];c[];redo if b[]}
k[]end

这比其他条目大很多,但是我认为它更好地抓住了问题的实质。实际上,这使您几乎可以像示例一样编写代码:

def f a,b,c,&d
a[]
k=->{d[];c[];redo if b[]}
k[]end


i = 0 # Have to pre-declare i to have the closures work properly
f(proc{ i = 0 }, proc{ i < 1000 }, proc{ i += 1}) do
  p i
end

# Been a long time since I've actually used for's so took a long
# time to think of a non-trivial use.

j, sum = 0, 0 # Pre-declare variables for the closures

goal = 1000

f(proc{ j = 1; sum = 1 }, proc{ sum < goal }, proc{ j += 1 }) do
  sum = sum * j
end

puts "The next largest factorial after #{goal} is #{j-1}! at #{sum}"

5

C#,70 57个字符

C#并不是代码高尔夫的首选武器,但我认为我可以尝试一下:

void f(int i,Func<int,bool>j,int k){if(j(i)) f(i+k,j,k);}

这不仅执行了最多计数1000的任务;而是尝试for为任何任务实际复制循环行为。这似乎更接近挑战的意图,但也许就是我。

展开:

void f(int i, Func<int, bool> j, int k)
{
    if (j(i))
    {
        f(i + k, j, k);
    }
}

用法非常类似于for循环语法:

f(0, i => i < 1000, 1);  

4

蟒蛇

具体情况:

exec("print i,"+";")*1000

一般而言:

exec("f"+";")*1000

其中“ f”是您的代码。可能不适用于所有情况。


NameError:名称'i'未定义
JB

我已经解决了。另外,我假设我是预定义的。

2
如果它是预定义的,那么它将不会随着迭代而改变。for循环不是这样工作的。
JB

有道理。我想;i=+1在逗号后需要它。我确实说过,这不适用于所有情况。

exec 'i=0;'+1000*'print i;i+=1;'会做的工作。
flnk

4

C:循环的基数为33个字符(假设允许goto)

int i=0;s:if(i<1000){/`*code inside for loop here`*/i++;goto s;}


int i=0;s:if(i<1000){printf("%d ",i);i++;goto s;}



2

JavaScript-测试用例中的39个字符

Chrome,Opera和IE : eval(s="i<1e3&&eval(s,print(i++))",i=0)。在Safari上“超出调用堆栈大小”并在Firefox上“过多递归”失败了。

Firefox : (function f()i<1e3&&f(print(i++)))(i=0)。这使用Mozilla的非标准“表达式闭包”功能来消除一对花括号。

注:更改print(i++)alert(i++),如果你需要。您可以更改1e3100减少Safari的迭代次数。


print呼叫放入eval呼叫中确实很聪明。
贾斯汀·摩根

2

QBasic(24个字符)

1?i:i=i+1:IF i<1E3THEN 1

扩展为:

1 PRINT i: i = i + 1: IF i < 1000! THEN 1

注意:这假设i其原始值仍为0。


2

J,?<10个字符

f^:1000

在J中,几乎没有循环;相反,通常使用数组和遍历它们的隐式循环。例如,要对整数1..100求和,请将(/)“动词”加(+)应用于数组1..100(i.101)

+/i.101
5050

要显示数字0..99,我们只需构造数组:

i.100
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...

^:是“权力”动词;f^:1000是类似于exec()*1000python中的东西。


2

C#,58个字符

更新: D'oh ...看来这与Eelvex击败我几分钟几乎完全相同

不是很聪明-只是.NET中的简单递归。

void f(int c,int m){Console.Write(c+" ");if(c++<m)f(c,m);}

或取出“ for循环”的正文(35个字符):

void f(int c,int m)if(c++<m)f(c,m);

允许播种初始值和最大值。


2

斯卡拉

Nemo157的答案中得到启发:

def myfor(test: =>Boolean, inc: =>Unit)(stmts: =>Unit) : Unit =
        if (test) {
                stmts
                inc
                myfor(test, inc)(stmts)
        }

可以这样使用:

var i = 0
myfor(i<1000, i+=1) {
        print(i+" ")
}

高尔夫(62):

def f(t: =>Boolean,i: =>Unit)(s: =>Unit){if(t){s;i;f(t,i)(s)}}

要么:

def myfor[A](init: A, test: (A)=>Boolean, inc: (A)=>(A))(stmts: =>Unit) : Unit = 
        if (test(init)) {
                stmts
                myfor(inc(init), test, inc)(stmts)
        }

myfor[Int](0, _<10, _+1) {
        println("loop")
}

2

PowerShell 18

filter p{$i=$_;$i}

1-10

PS C:\> (1..100 | p)-join' '
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 6
4 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 

是的,它完全没有用,您必须重写该函数才能执行任何有用的操作。但这不是重点吗?:)


打印换行符作为分隔符?...用空格1 ...-取消我的资格。:)
未知用户

1
过滤器p {“ $ _”} --- :)
Ty Auvil

我不确定这是否应取消资格,因为从技术上来说,它就像在使用管道一样foreach
Iszi 2013年

2

Clojure
(map #(print (str % " ")) (range 1 (inc 100)))

将print替换为要执行的功能。
使用(inc 100)或101作为最后一个值。


2

Perl,21个字符

map{print"$_ "}0..999

映射是循环的一种。不要作弊!:-P
Chris Jester-Young

这个注释是无稽之谈,因为我们必须编写等效于for循环的东西。如果我们符合标准,那将永远是作弊,或者会有什么不同?明确的gotos?递归?
用户未知,

@克里斯很好,我在回答那个问题之前在聊天中明确地问过OP。
JB

2

Perl最简单-18个字符(确定,作弊)

print"@{[0..999]}"

输出:0 1 2 3 ... 998 999

但:

Perl regex / goatse op(real pseudoloop)-39(16)个字符

()="@{[0..999]}"=~/\d+(?{print"$& "})/g

“基本循环”为16个字符

()=             =~/\d+(?{          })/g

输出:0 1 2 3 ... 998 999

问候

机器人


2

Javascript-86个字符

e=eval,n=function(j,k,c){if(e(j))e(k),c(),n(j,k,c)},f=function(i,j,k,c){e(i),n(j,k,c)}

也许不是最短的javascript解决方案,但它会复制迭代器声明,迭代器操作以及循环条件。

用例示例:

f('a = 0', 'a < 9', 'a++', function() {
    console.log(a);
});

2

C(无递归,无权执行)

#include <stdio.h>

int main()
{
    puts("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999");
    return 0;
}

完全按照定义,不是吗?


它复制输出,但实际上与for循环的规范不匹配。但是,我认为它很好:)。但是你应该打高尔夫球。
Twometer

抱歉,这不是代码高尔夫球,昨天没看过……
Twometer

1
;; for (int index=1, result=1; !cmp(result, max); index=incr(index)) result=body(index,result);
((lambda (index result cmp max body incr)
   ((lambda (f n i)
      (if (cmp i max) n
          (f f (body i n) (incr i))))
    (lambda (f n i)
      (if (cmp i max) n
          (f f (body i n) (incr i)))) result index)) 1 1 > 1000 (lambda (i n) (printf "i:~a~nn:~a~n" i n) (* n i)) (lambda (x) (+ x 1)))

4
请标记此答案使用的语言。
内森·奥斯曼

1

LISP,91个字符

(defun m(x)(if(= 1000(length x))x(m(append x(list(1+(car(last x))))))))
(mapcar #'f(m'(0)))

标签可能会更短。

用法示例:

(defun f(x) (format t "~a " x))
(mapcar #'f (m '(0)))
0 1 2 3 4 5 6 7 8 9 10 11 12 ...  997 998 999


1

Python3-27个字符

any(map(print,range(1000)))

凉。对于出色的输出:print(" ".join(map(str,range(1000))))
Wok

1

Windows批处理文件,65

set I=%S%
:l
if %I% GEQ %E% goto :eof
call %C%
set /a I+=1
goto l

测试文件:

@echo off
set S=0
set E=100
set "C=<nul set /p X=%%I%% "
call for.cmd

如果循环始终从0开始,则可以节省两个字节。

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.