镭射困境


31

镭射困境

Disarium定义为以下数字:

加上各自位置的数字总和等于原始数字


您的任务

您对数字归类为disarium有一种奇怪的迷恋。在您中,遵循disarium方式的需求是如此之大,以至于您拒绝阅读任何给定书中任何没有disarium编号的页面。您有两个问题:

  1. 你的教授刚分配您可以从页面读取你的课本nm
  2. 上周,您真的很难受打击,似乎不记得如何以编程方式确定数字是否被认为是一个稀有事物。

时间至关重要,因此确定您需要阅读的页面的代码必须尽可能短。

您需要确定一个包容的范围内的所有disarium的n通过m

镭的例子

89 = 8 1 + 9 2

135 = 1 1 + 3 2 + 5 3

518 = 5 1 +1 2 + 8 3

这是代码高尔夫球,因此最少的字节数获胜!

这是A032799的全部序列。


@Fatalize范围包括在内,我将编辑问题以反映这一点。
CraigR8806

是否有任何保障范围nm?有一个很大的铱(12157692622039623539),答案应该能够识别出来吗?
林恩

@Lynn鉴于已经有了许多解决方案,我想说范围应该没有界限。
CraigR8806

2
@林恩 没有大于22位数字的球,因此某种程度上范围已经确定。
疯狂物理学家

3
@MistahFiggins请转到问题底部的OEIS链接。您会发现一个证明Disarium序列确实是有限的证明。
CraigR8806

Answers:


11

Perl 640 39个字节

{grep {$_==sum .comb Z**1..*},$^a..$^b}

在线尝试!

怎么运行的

{                                     }  # A lambda.
                              $^a..$^b   # Range between the two lambda arguments.
 grep {                     },           # Return numbers from that range which satisfy:
               .comb Z  1..*             #  Digits zipped with the sequence 1,2,3,...,
                      **                 #  with exponentiation operator applied to each pair,
           sum                           #  and those exponents summed,
       $_==                              #  equals the number.

8

Python2,98个 89 88 84字节

lambda n,m:[x for x in range(n,m+1)if sum(int(m)**-~p for p,m in enumerate(`x`))==x]

可怕。会变短。开始看起来更好

这是我的递归尝试(86字节):

f=lambda n,m:[]if n>m else[n]*(sum(int(m)**-~p for p,m in enumerate(`n`))==n)+f(n+1,m)

感谢@Rod节省了4个字节!rangeenumerate等。


切换到enumerate,您可以int(n)改用int(`x`[p])
Rod Rod

7

Perl,43个字节

map{say if$_==eval s/./+$&**$+[0]/gr}<>..<>

在线尝试!

伙计们,正则表达式真的很强大。

说明

代码要做的第一件事是读取两个整数作为输入<>,并使用来创建从第一个到第二个的范围..。然后,它使用标准map函数迭代此范围,并将以下代码应用于每个值:say if$_==eval s/./+$&**$+[0]/gr。这看起来像胡言乱语,但实际上是在发生这种情况。

map将其当前值隐式存储在变量中$_。如果没有给出任何Perl函数和操作,则使用此值。这包括正则表达式,例如s///替换运算符。

替换正则表达式包含四个部分:

  1. 要操作的字符串。通常,运算符=~用于将正则表达式应用于字符串,但是如果不存在此运算符,则将正则表达式应用于隐式变量$_,该隐式变量通过map函数包含我们的当前数字。
  2. 要搜索的字符串。在这种情况下,我们正在搜索任何单个非换行符,以通配符表示.。实际上,我们正在捕获每个数字。
  3. 要替换的字符串。我们用加号代替+数学表达式,再加上一些神奇的Perl变量,这些变量使一切变得更加容易。

特殊的标量变量$&始终包含上一次成功的正则表达式捕获的全部,在这种情况下为单个数字。特殊数组变量@+始终包含最后一次成功匹配的匹配后偏移量列表,即匹配之后的文本索引。 $+[0]$_紧随其后的文本的索引$&。在的情况下135,我们捕获了数字1,并捕获了135紧随其后的文本(即35)为1,这是我们的指数。因此,我们想将$&(1)提升为$+[0]得到1。我们想将3提高到2的幂,得到9。我们想将5提高到3的幂,得到125。

如果输入是 135,则结果字符串为+1**1+3**2+5**3

  1. 正则表达式修改标志。在这里,我们使用两个正则表达式标志- /g/r/g告诉解释器在找到第一个后继续进行替换(否则我们将以结束+1**135)。/r告诉解释器不要修改原始字符串,而是返回替换后的字符串。这很重要,因为否则它会覆盖$_,我们需要它进行比较。

完成整个替换后,我们将获得一个数学表达式,该表达式将通过eval函数进行求值。 +1**1+3**2+5**3被评估为1 + 9 + 125 = 135与原始数字进行比较135。由于这两个相等,因此代码将打印该数字。


美丽的解决方案。(请注意,这是行不通的,因为第一个输入为0,但我不确定这很重要)。高尔夫几个字节:map$_-eval s/./+$&**$+[0]/gr||say,<>..<>
达达

并且"@+"$+[0]::) 短1个字节
Dada

7

JavaScript(ES7),105 91 89 88 83 79 82 81字节

感谢Arnauld节省了20B,而ETHProductions节省了6B!

a=>b=>[...Array(b).keys()].filter(c=>c>=a&([...c+''].map(d=>c-=d**++e,e=0),!c))

用法

将函数分配给变量,并为其指定最小值和最大值。例:

f=a=>b=>[...Array(b).keys()].filter(c=>c>=a&([...c+''].map(d=>c-=d**++e,e=0),!c))
f(0)(90)

输出量

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 89]

进一步打高尔夫球

这似乎很不错,但是总有改进的余地...我认为。


是的,实际上要短很多。谢谢!
路加福音

1
您可以更改d**(e+1)d**-~e保存两个字节。
ETHproductions

感谢您的提示,添加了它。在我们击败Python之前
路加福音

您可以使用&代替&&。还有一个字节要去…
Arnauld

我只是在我的本地副本中更改了它…猜猜你更快。
路加福音

6

JavaScript(Firefox 52 +),68个字节

f=(n,m)=>(e=0,[for(d of t=n+'')t-=d**++e],t||alert(n),n-m&&f(n+1,m))

通过输出的递归函数 alert。可在Firefox开发人员版中使用,您可以在此页面上下载该版本。Firefox的早期版本不支持该**运算符,并且其他浏览器也不支持[for(a of b)c]语法。

测试片段

这使用的.map不是数组推导,Math.pow而是**,因此它应在所有支持ES6的浏览器中正常工作。


6

05AB1E,12个字节

感谢Emigna节省了2个字节

ŸvygLySmOyQ—

在线尝试!

Ÿ            # push [a .. b]
 vy          # for each
   gL        # push [1 .. num digits]
     yS      # push [individual digits]
       m     # push [list of digits to the power of [1..num digits] ]
        O    # sum
         yQ— # print this value if equal

ŸvygLySmOyQ—应该工作12个字节。
Emigna

5

Python 3,100个字节

lambda n,m:{*range(10),89,135,175,518,598,1306,1676,2427,2646798,0xa8b8cd06890f2773}&{*range(n,m+1)}

不是最短的方法,而是一种非常可爱的方法。有限地存在许多镭。请参阅OEIS页面以获得很好的证明。这些都是。


这是硬编码的使用,它是一个漏洞meta.codegolf.stackexchange.com/a/1063/55243我建议您更改答案以符合标准规则
乔治

5
我不认为这违反了硬编码规则,因为该程序仍然可以“工作”并且输出不是硬编码的。
Alex Howansky '17

4

R,100字节

function(n,m,x=n:m)x[sapply(x,function(y)sum(as.integer(el(strsplit(c(y,""),"")))^(1:nchar(y)))==y)]

带有n和的未命名函数m。与R中一样,将整数拆分为数字向量很麻烦,并且占用大量字节。这使函数相对较慢,并且仅适用于32位整数。


4

果冻,11字节

D*J$S⁼
rÇÐf

在线尝试!

在@miles的帮助下,将其从16降至11!

说明:

rÇÐf    Main link, arguments are m and n
r       Generate a list from m to n
 Ç      Invoke the helper link
  Ðf    And filter out all that don't return 1 on that link

D*J$S⁼  Helper link, determines if item is Disarium
D       Break input (the current item of our list in Main) into digits (135 --> [1, 3, 5])
  J$    Create a range from 1 to x, where x is the number of digits             [1, 2, 3]
 *      Raise each digit to the power of their respective index 
    S⁼  And return a 1 if the sum of powers is equal to the helper-link's input

您可以J用来获取索引。一种较短的方法是D*J$S⁼将您的两个链接合并为一个
英里

大约20秒钟前就得出了这个结论。谢谢!
steenbergh

3

CJam,23个字节

q~),\>{_Ab_,,:).#:+=},p

在线尝试!

说明

q~                      Get and eval all input
  ),\>                  Get the range between m and n, inclusive
      {                 For each number in the range...
       _Ab               Duplicate and get the list of digits
          _,,:)          Duplicate the list, take its length, make the range from 1 to length
               .#        Vectorize with exponentiation; computes first digit^1, second^2, etc
                 :+      Sum the results
                   =     Compare to the original number
                    },  Filter the range to only numbers for which the above block is true
                      p Print nicely


3

Python 2.X,92个字节

lambda m,n:[k for k in range(m,n+1)if sum(int(j)**(i+1) for i,j in enumerate(list(`k`)))==k]

之后使用无用的空格(i+1),但这不是问题,当您通过做来摆脱括号时-~i
Yytsi'1

那会让我的尝试和您的完全一样!
hashcode55

几乎。你有list('k'),我没有。但是,您仍然可以删除空格:)
Yytsi

3

Python 2,84个字节

完整的程序方法,当前长度与lambda解决方案相同。

a,b=input()
while a<=b:
 t=p=0
 for x in`a`:p+=1;t+=int(x)**p
 if t==a:print a
 a+=1

在线尝试!


嗯 我考虑了几乎准确的答案,但由于与混淆而被丢弃input()。非常好!+1。
Yytsi'1

3

Japt,15个字节

òV f_¥Zì £XpYÄÃx

在线测试!这是@obarakon和我之间的合作。

怎么运行的

òV f_¥Zì £XpYÄÃx   // Implicit: U, V = input integers
òV                 // Create the inclusive range [U...V].
   f_              // Filter to only the items Z where...
               x   //   the sum of
      Zì           //   the decimal digits of Z,
         £XpYÄÃ    //   where each is raised to the power of (index + 1),
     ¥             //   is equal to Z.
                   // Implicit: output result of last expression

在最新版本的Japt中,x接受一个函数作为参数,这使我们可以使用另一个字节:

òV f_¥Zì x@XpYÄ

在线测试!


2

Clojure,107个字节

#(for[i(range %(inc %2)):when(=(int(apply +(map(fn[i v](Math/pow(-(int v)48)(inc i)))(range)(str i))))i)]i)

实施该方程非常长。


可以通过这样做节省几个字节(.pow(-(int v)48M)
悬崖根

2

TI-Basic,85个字节

Input 
For(I,X,Y
If I<=9 or sum(I={89,135,175,518,598,1306,1676,2427,2646798,12157692622039623539
Disp I
End

我不知道允许硬编码。:)
亚伯汤姆

@AbelTom好,这个系列只有20个术语确实有帮助。此外,在TI-Basic中将数字转换为字符串会占用大量字节。只有其他解决方案是对int(log(每个数字求幂,然后再求幂。也许这段时间较短,但我对此表示怀疑。
Timtech '17

该输入方法非常聪明,但有点粗略。您需要处于FUNC模式下,并且必须设置窗口以包括您的输入点。对我来说似乎不够便携。
雅各布

@JakobCornell默认情况下,计算处于FUNC模式,尽管我确实看到了您在说输入分辨率。但是,这种方法在打高尔夫球中非常普遍。您总是可以Prompt X,Y代替。
Timtech '17

2

Haskell,61个字节

n#m=[i|i<-[n..m],i==sum(zipWith(^)(read.pure<$>show i)[1..])]

用法示例5 # 600-> [5,6,7,8,9,89,135,175,518,598]

检查i范围内的每个数字[n..m]。通过将数字i变成字符串(show),并使每个字符成为一个元素字符串(pure),再将其变成整数(),来提取数字read。将这些数字元素明智地压缩[1..]通过函数^将然后采用sum


2

PHP,92 91 88字节

节省了3个字节@AlexHowansky

for([,$n,$m]=$argv;$n<=$m;$s-$n++?:print"$s,")for($i=$s=0;_>$b=($n._)[$i++];)$s+=$b**$i;

从命令行参数获取输入;打印尾随逗号。用运行-r


1
Save three with for([,$n,$m]=$argv;$n<=$m;
Alex Howansky

Strange that print works there but echo doesn't. I guess because echo doesn't return anything -- not even null, oddly.
Alex Howansky

@AlexHowansky: It´s also strange that "$n"[index] and "_$n"[index] produce parse errors while "89"[index] and $s="$n";$s[index] are perfectly fine.
Titus

Hmm yes, that does seem odd at first, but after checking the docs, it appears they do explicitly say that the feature works only for string literals.
Alex Howansky

Heh heh well this works, but it probably doesn't save you any bytes: ("_$n")[index]
Alex Howansky

2

Mathematica, 59 bytes

Select[Range@##,Tr[(d=IntegerDigits@#)^Range@Length@d]==#&]&

Unnamed function taking two integer arguments and returning a list of integers. (d=IntegerDigits@#)^Range@Length@d produces the list of digits of a number to the appropriate powers; Tr[...]==# detects whether the sum of those digit-powers equals the original number.


2

MATLAB, 88 73 bytes

@(n,m)find(arrayfun(@(n)n==sum((num2str(n)-48).^(1:log10(n)+1)),n:m))+n-1

Original answer:

function g(n,m);a=n:m;a(arrayfun(@(n)n==sum((num2str(n)-'0').^(1:floor(log10(n))+1)),a))

num2str(n)-'0' splits a n into a vector of its digits, and 1:floor(log10(n))+1 is a vector holding one to the number of digits in n. Thanks to log for the golf down to an anonymous function, saving 15 bytes.


1

Haskell, 82 76 75 bytes

n!m=[x|x<-[n..m],x==x#(length.show)x]
0#i=0
n#i=(div n 10)#(i-1)+mod n 10^i

Try it online! Usage: 5 ! 175

This checks each number in the range n to m if its a disarium number and is hence quite slow for big m.


Faster version: (93 bytes)

n!m=[x|x<-[0..9]++[89,135,175,518,598,1306,1676,2427,2646798,12157692622039623539],x>=n,x<=m]

Try it online!


1

C (gcc), 136 bytes

r[]={0,0};f(n){if(n)f(n/10),r[1]=pow((n%10),*r)+r[1]+.5,r[0]++;else*r=1,r[1]=0;}g(m,x){for(;m<=x;m++){f(m);if(m==r[1])printf("%d,",m);}}

Header defining pow on TIO because for some reason it didn't auto include pow. My computer did, so I'm going to roll with that.

Try it online!


1

MATL, 16 bytes

&:"@tFYAtn:^s=?@

Try it online!

&:        % Input two n, m implicitly. Push array [n n+1 ... m]
"         % For each k in that array
  @       %   Push k
  tFYA    %   Duplicate. Convert to decimal digits
  tn:     %   Duplicate. Push [1 2 ... d], where d is the number of digits
  ^       %   Element-wise power
  s       %   Sum of array
  =       %   Compare with previous copy of k: is it equal?
  ?       %   If so
    @     %     Push k
          %   End, implicit
          % End, implicit
          % Display stack, implicit

1

Batch, 115 bytes

@for %%d in (0 1 2 3 4 5 6 7 8 9 89 135 175 518 598 1306 1676 2427 2646798)do @if %%d geq %1 if %%d leq %2 echo %%d

Batch only has 32-bit arithmetic which has no way of comparing the last disarium number, but if you insist on string comparisons, then for 402 bytes:

@echo off
for %%d in (0 1 2 3 4 5 6 7 8 9 89 135 175 518 598 1306 1676 2427 2646798 12157692622039623539)do call:c %1 %%d&&call:c %%d %2&&echo %%d
exit/b
:c
call:p %1 %2
set r=%s%
call:p %2 %1
:g
if %r:~,1% lss %s:~,1% exit/b0
if %r:~,1% gtr %s:~,1% exit/b1
if %r%==%s% exit/b0
set r=%r:~1%
set s=%s:~1%
goto g
:p
set s=%1
set t=%2
:l
set s=0%s%
set t=%t:~1%
if not "%t%"=="" goto l

1

Python 2, 100 bytes

for i in range(input(),input()+1):x=sum(int(`i`[n])**-~n for n in range(len(`i`)));print("",x)[x==i]

I haven't had a chance to run this yet (doing this on my phone).


This doesn't work. Incorrect syntax and when corrected, would print only boolean values. Starts from the exponent 0, which is also incorrect. Also, you don't need the square brackets inside sum.
Yytsi

This isn't checking for disarium numbers.
hashcode55

@hashcode55, fixed (?)
Daniel

@TuukkaX, now it should work I think
Daniel

I'm not on computer, but this should print a newline on each iteration, where i is a Disarium. I have no idea whether this is allowed, but I would say no, since the output gets very blank.
Yytsi

1

Scala, 132 129 bytes

(% :Int,^ :Int)=>for(i<- %to^)if(((0/:(i+"").zipWithIndex)((z,f)=>{z+BigInt(f._1.toInt-48).pow(f._2+1).intValue}))==i)println(i)

129 edit: Changing the for loop's variable name from & to i saved three spaces.


Explanation

For each value in the input range:

  • convert it to a string with +""
  • use zipWithIndex to produce a list of tuples containing a char of the digit and its index
  • fold the list by returning each char's int value minus 48 (lines up to 0-9) to the power of its list index plus one (to start at ^1)
  • if the result matches the input, print it

Comments

Finally got around to learning how fold and zipWithIndex work. I'm unhappy with the int conversions, but I am pleased with the succinctness of fold and zipWithIndex.


1

Octave, 88 87 bytes

Thanks to MattWH for saving a byte (f(x)-48 vs f(x)-'0')

@(n,m,f=@num2str,a=n:m)a(a==cell2mat(arrayfun(@(x){sum((f(x)-48).^(1:nnz(f(x))))},a)))

To run:

>> f=@(n,m,f=@num2str,a=n:m)a(a==cell2mat(arrayfun(@(x){sum((f(x)-'0').^(1:nnz(f(x))))},a))) 
>> f(0,1000)
ans = 
      1     2     3     4     5     6     7     8     9    89   135   175   518   598

Explanation

@(n,m,                                              % Create an anonymous function and pass it n and m as paramteres
    f=@num2str,                                     % Will be using the num2str mehtod twice, set the variable f to the handle to save on bytes
        a=n:m)                                      % Create a vector 'a' and populate it with the numbers n through m
            a(a==                                   % Logically index into a, where the values of a match Disarium numbers
                cell2mat(                           % Convert the cell array returned by arrayfun into a matrix, so we can use it in the logical index
                    arrayfun(@(x){                  % Call the following function on every element of a, using the index named 'x'
                        sum(                        % Sum the matrix that results from the following computation
                            (f(x)-'0')              % Convert the value at index x into a string, then break it into a matrix by subtracting the string '0'.
                                                    % This results in the matrix [1 3 5] for the number 135.
                                .^                  % Compute the element-wise power with the following matrix
                                    (1:nnz(f(x)))   % Create a matrix with the range 1 to the length of the number at index x. This results in the matrix 
                                                    % [1 2 3] for the number 135.
                        )                           % Closes the sum statement
                    },a)                            % Closes the arrayfun statement, passing the matrix a to be operated on
                )
            )

1

C 175 169 bytes

f(a,b){for(j=a;j<b;j++){n,i=0,x=0;s=0;n=j;while(n!=0){n/=10;i++;}a[i];n=j;while(n!=0){a[i-x-1]=n%10;n/=10;x++;}for(x=0;x<i;x++)s+=(int)pow(a[x],x+1);if(j==s)printf("%d ",s);}}

Ungolfed version:

void f(int a, int b)
{

  for(int j=a; j<b;j++)
  {
    int n,i=0,x=0;
    int s=0;
    n=j;

   //Convert each number from 'n' to 'm' and store it in an int array 
   while(n)
   {
     n/=10;
     i++;     
   }
   int a[i]; 

   n=j;       
   while(n)
   {
    a[i-x-1]=n%10;
    n/=10;
    x++;     
   }

  //Calculate sum of digits powered with their respective position
  for(x=0;x<i;x++)
   s+=(int)pow(a[x], x+1);

   //Print Desarium
   if(j==s)
    printf("%d ", sum);     
 }

}

Can be shortened in some way, but I don't see it at the moment.

@TuukkaX Thanks for saving 6 bytes.


Both n!=0 can be changed to n.
Yytsi

You're right, that does make sense!
Abel Tom

0

Java

s->{long i=0,j=0,c,d;for(;j!=s;){String []f=Long.toString(i).split("");for(d=0,c=0;d<f.length;)c+=Math.pow(Long.valueOf(f[d]),++d);if(i==c)j++;}return i;}

Explanation

s    - index
i    - iteration variable
j    - matches
c    - sum of each digit^its index
d    - index of digit in i

0

Python 3: 131 Bytes

n=int(input())
m=int(input())
R=[x for x in range(n,m+1)]
O=[sum(map(int,str(x)))for x in R]
F=[(x**(O.index(x)))for x in O]
L=[x for x in F for w in R if x==w]
print(list(set(L)))

After creating this code, it's become apparent that there are a limited number of disariums, so it might be more feasible to check for these explicitly rather than using so much list comprehension which is tough on big inputs to this solution.

Try it online!

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.