196算法代码高尔夫


35

196算法编写一个简短的程序。该算法从整数开始,然后向其加反数,直到达到回文。

例如

input = 5280
5280 + 0825 = 6105
6105 + 5016 = 11121
11121 + 12111 = 23232
output = 23232

输入项

一个不是lyrchrel数的整数(也就是说,在此算法下,它最终会产生回文,而不是无限地继续)

输出量

回文达到了。


6
因为您的问题可能是唯一涉及196算法的问题。制作一次性标签是没有用的。
克里斯·杰斯特·杨

2
我的意思是,你的问题很可能是唯一一个曾经涉及到这个话题,即使在2年的时间。:-)
Chris Jester-Young

1
@克里斯:好吧,196算法是一个非常受欢迎的算法,它有很多不同的名字。不过要确定的是,我将在两年的时间过后再发布一个问题;)
Eelvex 2011年

1
@GigaWatt也,我没有读懂你的拳头问题:)只是不要打扰A023108s的情况。
Eelvex 2012年

1
@Joel和A023108一样,只需忽略它们(就像您对它们一无所知一样);我们不知道是否存在。
Eelvex 2012年

Answers:


10

APL(22个字符)

{a≡⌽a←⍕(⍎⍵)+⍎⌽⍵:a⋄∇a}⍞

这在Dyalog APL中有效。这是从右到左的解释:

  • { ... }⍞:从用户那里获得字符()的输入,并将其输入到我们的函数({ ... })中。
  • 在直接函数中(分隔语句,因此我们从左到右查看它们):
    • a≡⌽a←⍕(⍎⍵)+⍎⌽⍵ : a:评估()正确的论点()反向(),并将其添加到评估的正确论点本身。然后,格式化结果(;即给出其字符表示形式),将其赋给变量a,最后测试a'reverse是否等效于a(即a回文?)。如果为true,则返回a;除此以外...
    • ∇a:反馈a到我们的函数中(是隐式的自引用)。

例:

      {a≡⌽a←⍕(⍎⍵)+⍎⌽⍵:a⋄∇a}⍞
412371
585585

2
它保存了一些字符以使用数字输入。{⍵=A←⍎⌽⍕⍵:⍵⋄∇A+⍵}⎕。您保存大括号,反向和评估。
marinus 2012年

10

GolfScript,29个字符

~]{{.`.-1%.@={;0}{~+1}if}do}%

精选评论

do当然,程序的核心是循环。所以我只介绍一下。

  1. .` 复制数字并将其字符串化。
  2. .-1% 复制该字符串版本并将其反转。
  3. .@ 复制反向版本,并将原始非反向版本放在最前面。

因此,数字为5280。在此阶段,堆栈为:5280 "0825" "0825" "5280"。为进行比较设置了阶段。(比较之后,5280 "0825"无论如何都将保留堆栈---弹出要比较的项目。)

  1. 如果字符串和反向字符串相同,则我们不在乎反向字符串,因此只需将其弹出(;)并返回0(以结束do循环)即可。
  2. 如果不匹配,则求值(~)颠倒的字符串(使其成为数字),将(+)添加到原始数字,然后返回1(继续do循环)。

4
您确定没有按键盘上的随机键吗?看起来像是……

1
@ M28:与Perl相比,GolfScript看起来更像是线噪,不是吗?;-)
Chris Jester-Young

我为您感到抱歉,编写该代码一定很痛苦

@ M28:这几乎没有我为Luhn算法编写的解决方案那么痛苦。只是考虑一下。:-P
Chris Jester-Young

您的家人担心您

10

Python 2,55个字节

遵循JPvdMerwe的建议:

n=input()
while`n`!=`n`[::-1]:n+=int(`n`[::-1])
print n

Python 2、62:

n=raw_input()
while n!=n[::-1]:n=`int(n)+int(n[::-1])`
print n

呵呵..)))))))))
Nakilon

2
通过n将int视为可以缩短6个字符的代码,请检查以下代码:meta.codegolf.stackexchange.com/q/75/62
JPvdMerwe 2011年

似乎我不小心将新添加到文件末尾的新行vim包括在内。真正的计数为55
JPvdMerwe

7

红宝石-56个字符

x,r=gets
x="#{x.to_i+r.to_i}"until x==r=x.reverse
puts x

7

仅锻炼我的Pyth技能,而不是认真的竞争者。

Pyth,16个字节

L?bqb_by`+vbi_bTyz

等同于Python 3:

y=lambda b:b if b==b[::-1] else y(str(eval(b)+int(b[::-1],10)))
print y(input())

只是尝试一些已经解决的旧挑战,所以不是认真的竞争者。
swstephe 2014年

1
如果提出了较短的解决方案,一些挑战性的作者将更新接受的答案,因此我认为可以通知OP,从技术上讲这不是有效的提交,这是公平的。(不要误会我的意思,我也喜欢用CJam回答旧的挑战-而我只是在几分钟前做的。我只是说,如果愿意,请注意,该语言比挑战。)
Martin Ender 2014年

实际上,“不是认真的竞争者”会使答案被删除,但我不认为有任何理由不应该将其视为认真的竞争者。
pppery

6

J 25 27 31

f=:(+g)^:(~:g=.|.&.":)^:_
e.g.
f 5280
23232

6

CJam,22 21字节

CJam是在询问此问题后创建的,因此从技术上讲,它是无效的提交。但是我发现这个问题很有趣,所以去了:

r{__W%:X=0{~X~+s1}?}g

说明:

r{                 }g    "Read the input number as string and enter a while-do loop";
  __                     "Make 2 copies of the string number";
    W%:X                 "Reverse the second and store it in X";
        =                "Check if the number is already palindrome";
         0{      }?      "Put 0 on stack if it is palindrome, else, run the code block";
           ~             "Convert the string to int";
            X~           "Put the reverse string on stack and convert it to int too";
              +s         "Add the two numbers and covert back the result to string";

核心逻辑是,在每次执行时迭代中,您首先要检查回文是否实现。如果没有,请在数字后加上反号。算法几乎是什么!

在这里在线尝试


5

这是一个真正的竞争者,因为J已经存在了数十年。

J(16个字节)

(+^:~:|.&.":)^:_

这是一个动词,因此可以将其分配给J会话中的变量,并按如下方式使用:

   f =. (+^:~:|.&.":)^:_
   f 5280
23232

怎么运行的:

(+^:~:|.&.":)^:_
 +^:~:           add if unequal
      |.&.":     reverse under string format
 +^:~:|.&.":     add reverse unless a palindrome
(           )^:_ repeat until unchanged

4

蟒蛇:66

n=input()
while 1:
 r=int(`n`[::-1])
 if n==r:break
 n+=r
print n


4

斯卡拉82

def p(n:Int):Int={val s=n.toString.reverse.toInt
if(n==s)n else p(n+s)}
p(readInt)

4

JAGL Alpha 1.2-19,21 with stdin

不竞争,只是对我的语言有所了解,
期望stdin有一个数字

T~d{DddgCi+dgdC=n}uSP

说明

T~                       Get a line of input, and eval to an integer
  d                      Duplicate (for first round)
   {Ddd                  Drop last and duplicate twice
       gCi               Convert to string, reverse, and convert back to integer
          +d             Add to original and duplicate
            gdC          Convert to string, duplicate, reverse
               =n}       If it isn't a palindrome, keep going
                  uSP    Run until palindrome reached, then print output number

编辑。@Optimizer
globby

请不要一次编辑所有提交的内容以进行较小的编辑(例如版本号),因为这不必要地使首页变得混乱。一次执行2次或3次也可以,但是请等待几个小时,然后再进行系统的编辑。
Martin Ender 2014年

忘了它将推送到首页,我不好。@MartinBüttner
globby

4

05AB1E,7个字节(非竞争)

不竞争,因为该语言推迟了挑战。

码:

[DÂQ#Â+

说明:

[        # Infinite loop.
 DÂ      # Duplicate and bifurcate (which duplicates it and reverses the duplicate).
   Q#    # If the number and the number reversed are equal, break.
     Â+  # Add the reversed number to the initial number.

使用CP-1252编码。在线尝试!


您能否进一步解释分叉过程?
科纳·奥布莱恩

1
@CᴏɴᴏʀO'Bʀɪᴇɴ例如,在堆栈上是字符串hello。分叉将保留原始字符串,并推回该字符串。它是重复和反向的缩写。
阿德南

哦,我懂了。凉!谢谢
科纳·奥布莱恩

4

Brachylog,8个字节

↔?|↔;?+↰

在线尝试!

Brachylog简介视频中我看到并感兴趣的第一个Brachylog程序之一有些相似。

?↔?.|↔;?+↰.  (initial ? and the .s are implicit)

?↔?          % If the input and its reverse are the same,
   .         %   then the input is the output
    |↔;?+↰   % Or, add the input and its reverse, and call this predicate recursively
          .  % The result of that is the output

3

PHP- 54 48个字符

<?for($s=`cat`;$s!=$r=strrev($s);$s+=$r);echo$s;

测试:

$ php 196.php <<< 5280
23232

我将不得不记住$str = 猫的东西,以备将来打高尔夫球。比使用更好的东西STDIN,仍然比$argv[0]
拉玛先生

@GigaWatt:$ s ='m4'也应该起作用。
ninjalj 2012年

3

重击(64)

X=`rev<<<$1|sed s/^0*//`;[ $1 = $X ]&&echo $1||. $0 $(($1+$X))

致电:bash <文件名> <号码>


<文件名>的用途是什么?
Eelvex'3

2
@Eelvex脚本需要自行调用,因此您需要将其存储在文件中。
marinus 2012年

3

C#-103 99个字符

public int P(int i)
{
    var r = int.Parse(new string(i.ToString().Reverse().ToArray())));
    return r == i ? i : P(i + r);        
}

C#在高尔夫领域从来没有做得很好。优雅,但冗长。


1
您可以轻松地打更多球。使用“” +而不是.ToString并除去一些空格。
雅各布

3

Q(39个字符)

f:{while[x<>g:"I"$reverse -3!x;x+:g];x}

用法示例:

q)f 5280
23232

编辑:

现在降至34,相同用法:

{while[x<>g:"I"$(|) -3!x;x+:g];x} 5280


3

果冻,9个字节(非竞争)

一个非常简单的答案,仅适用于以深奥的语言编码的挑战。

ṚḌ+µŒḂ¬$¿

ṚḌ        : take the argument, reverse (and vectorize) it
  +µ      : add both
    ŒḂ¬$¿ : while the result isn't a palindrome

在线尝试!

如果该答案在任何级别上都不明确或错误,请随时指出。

感谢Dennis为我提供了这第一小段代码。


哇,并不是每个人都在第一篇文章中使用Jelly。
妮莎

使用深奥的语言在PPCG上发布答案是我的工作清单。果冻碰巧是我想到的第一个:)
z3r0

2

蟒蛇。85个字符:

s,i=str,int;rs=lambda q:s(q)[::-1];n=i(input());
while rs(n)!=s(n):n+=i(rs(n));print n

如果您不想在每次迭代中输出:

s,i=str,int;rs=lambda q:s(q)[::-1];n=i(input());
while rs(n)!=s(n):n+=i(rs(n))
print n

(少一个字符)


The task description states that only the final palindrome should be printed.
Joey

2

Windows PowerShell (63)

for($a=+"$input";-join"$a"[99..0]-ne$a){$a+=-join"$a"[99..0]}$a

I still hate it that there is no easy way to reverse a string.


Can be shortened by two characters if there only ever are ten digits of input. This way it's safe for long as well which is the largest integral type PowerShell supports anyway but still, I waste two chars.
Joey

2

Haskell 89 87 chars

r=read.reverse.show
main=getLine>>=print.head.filter(\x->x==r x).iterate(\x->x+r x).read

Somewhat readable version:

myFind p = head . filter p
rev = read . reverse . show
isPalindrome x = x == rev x
next x = x + rev x
sequence196 = iterate next
palindrome196 = myFind isPalindrome . sequence196

main = getLine >>= print . palindrome196 . read

The golfed version was created by manual inlining and renaming the remaining functions to single character names.


1
You can shorten this quite a bit by taking advantage of the underused function until from the Prelude, as well as extracting the pattern of applying a binary operator to x and r x. Also, use readLn instead of getLine and read. The result saves 20 characters: f%x=f x$read.reverse.show$x;main=readLn>>=print.until((==)%)((+)%)
hammar

@hammar: You could use the function monad and save even more: Define r=(=<<read.reverse.show) and just use r(==)`until`r(+). Apart from that saving, it doesn't need to be a full program, a valid submission could just be the unnamed function from before. This brings you down to 41 bytes: Try it online!
ბიმო

2

befunge, 57 bytes

"KCTS"4(&:0\v
\T\a*+\:0`jv>:a%\a/
0:+_v#-TD2$<^\
  @.<

though the code is places in a 4x19 grid, so might call it 76.

  • first line is initializeing, and reading input number
  • second line reverse first number in stack and put it in the second stack position.
  • and the third line checks if a number is palindrome.

2

C++ TMP (256 characters)

#include<cstdio>
#define Y(A,B,C,D)template<int N>struct A<C,D>{enum{v=B};};
#define Z(A)template<int N,int M>struct A{enum{v=
#define n 5194
Z(R)R<N/10,M*10+N%10>::v};};Y(R,N,0,N)Z(S)S<N+M,R<N+M,0>::v>::v};};Y(S,N,N,N)main(){printf("%d",S<n+R<n,0>::v,0>::v);}

This version could be shortened a bit, but a 256-character answer is hard to pass up. Here's an un-golfed version:

#include <iostream>

template<size_t N>
class Reverse
{
    template<size_t M, size_t R>
    struct Inner
    {
        enum { value = Inner<M/10, R*10 + M%10>::value };
    };

    template<size_t R>
    struct Inner<0, R>
    {
        enum { value = R };
    };

public:
    enum { value = Inner<N, 0>::value };
};

template<size_t N>
class OneNineSix
{
    template<size_t M, size_t R=Reverse<M>::value>
    struct Inner
    {
        enum { value = OneNineSix<M + R>::value };
    };

    template<size_t M>
    struct Inner<M, M>
    {
        enum { value = M };
    };

public:
    enum { value = Inner<N + Reverse<N>::value>::value };
};

int main()
{
    const size_t N = 4123;

    std::cout << OneNineSix<N>::value << std::endl;
}

2

Pyke, 13 bytes (noncompeting)

D`_b]D$XIsr)h

Try it here!

 `_b          -     int(reversed(str(num))
D   ]         -    [num, ^]
     D        -   _ = ^
      $       -  delta(^)
       XI     - if ^:
         s    -  num = sum(_)
          r   -  goto_start()
            h - _[0]

2

Add++, 57 bytes

L,BDbRBv
D,f,@,1]A+
D,g,@,1]A=
D,h,@,{f}A{g}Q{h}
L,{h}2/i

Try it online!

How it works

L,	; Create a function 'lambda 1'
	; Example argument:   [5280]
    BD	; Digits;     STACK = [[5 2 8 0]]
    bR	; Reverse;    STACK = [[0 8 2 5]]
    Bv	; Undigits;   STACK = [825]

D,f,@,	; Define a monadic function 'f'
	; Example argument:         [5280]
    1]	; Call 'lambda 1';  STACK = [825]
    A+	; Add the argument; STACK = [6105]

D,g,@,	; Define a monadic function 'g'
	; Example argument:          [5280]
    1]	; Call 'lambda 1';   STACK = [825]
    A=	; Equal to argument; STACK = [0]

D,h,@,	; Define a monadic function 'h'
	; Example argument:  [5280]
   {f}	; Call 'f';  STACK = [6105]
   A{g}	; If 'g'...
   Q	;   Return
   {h}	; Else call 'h'

L,	; Define a function, 'lambda 2'
	; Example argument: [5280]
   {h}	; Call 'h'; STACK = [46464]
   2/i	; Halve;    STACK = [23232]

2

Powershell, 63 62 bytes

-1 byte thanks to @AdmBorkBork

param($m)for(;$m-$s;$m=-join"$s"[-1..-"$s".Length]){$s+=$m};$s

Test script:

$f = {
param($m)for(;$m-$s;$m=-join"$s"[-1..-"$s".Length]){$s+=$m};$s
}

&$f 5280

1
You don't need the ; between param($m) and for.
AdmBorkBork

2

GNU dc, 46 bytes

Requires GNU dc, min version 1.4 (for R command).

[O~3RO*+rd0<R]sR[+lfx]sg[ddO~rd0<R+d3R!=g]dsfx

Input and output are top-of-stack, as usual. It takes a surprising amount of code to reverse digits in dc (unless I'm missing something, which is far from impossible). It does have the numeric range to behave nicely with inputs such as these (which will overflow 32-bit unsigned arithmetic, for example):

  • 89 ⇒ 8,813,200,023,188
  • 8997 ⇒ 16,668,488,486,661
  • 10677 ⇒ 4,668,731,596,684,224,866,951,378,664

Explanation

# Reverse digits, starting after first digit extracted
[O~3RO*+r d0<R]sR

# Recursion helper - add and recurse
[+ lfx]sg

# Main recursive function
[dd O~r d0<R+ d3R !=g]dsfx

Try it online! (Javascript)
Toby Speight

Might want to specify that this works only on GNU dc 1.4 and later, since it uses the new R command. Good solution, though!
Sophia Lechner

I'm working on a totally different approach but not sure it will wind up smaller.
Sophia Lechner

Thanks Sophia - I hadn't realised that R was new. Looking forward to seeing your method!
Toby Speight

Ah, nope...I tried a different approach to arranging the outside loop but it ended up about five bytes larger and no prettier. You win. =)
Sophia Lechner

2

R, 193 109 105 bytes

-84 bytes thanks to Giuseppe! -4 byes thanks to JayCe!

function(x){"-"=utf8ToInt
S=strtoi
"!"=rev
while({z=paste(S(x)+S(intToUtf8(!-x),10));any(-z!=!-z)})x=z
z}

Try it online!


1
You can (and should) choose a different way of doing this than string manipulation, but here are some golfing tips for the method you've chosen: strsplit(x,"") is shorter than strsplit(x,NULL), and el(L) is shorter than L[[1]]. as.double is shorter than as.numeric and strtoi is shorter than both; instead of setting t just use it directly in your if statement. also this is a recursive function if I'm not mistaken, so you need to put f= as part of your submission.
Giuseppe

@Giuseppe Got it. Thanks for the tips. I'll keep working on this. It's easier for me to just get something that works then go back and optimize.
Robert S.

1
Hehehe, no worries. If you're hell-bent on using strings (or forced to by the problem), consider utf8ToInt to convert to digits and intToUtf8 to convert back. That'll be a big byte saving!
Giuseppe


1
Save 4 more bytes by using - in place of U. I also replaced rev with ! but it does not save any byte...
JayCe
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.