이산 딜레마


31

이산 딜레마

Disarium은 다음과 같은 숫자로 정의됩니다.

해당 위치로 구동되는 자릿수의 합은 원래 숫자와 같습니다.


당신의 작업 :

당신은 disarium으로 분류 된 숫자에 대한 이상한 집착이 있습니다. 당신이 것을 disarium의 방법을 따라야 할 필요성은 너무 중대하다 거부 주어진 책이 아닌 disarium 번호 페이지를 읽을 수 있습니다. 두 가지 문제가 있습니다.

  1. 교수님이 방금 교과서를 읽도록 페이지 n에서 페이지로m
  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

에 어떤 보장 범위 있는가 n와는 m? 매우 큰 disarium (12157692622039623539)이 있는데 답변에서이를 식별 할 수 있어야합니까?
Lynn

@Lynn 이미 많은 솔루션이 있다고 가정하면 범위에 경계가 없어야한다고 말하고 싶습니다.
CraigR8806

2
@ 린. 이산> 22 자리가 없으므로 범위가 이미 제한되어 있습니다.
Mad Physicist

3
@MistahFiggins 질문 하단의 OEIS 링크로 이동하십시오. Disarium 시퀀스가 ​​실제로 유한하다는 증거를 찾을 수 있습니다.
CraigR8806

답변:


11

펄 6 , 40 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)

4 바이트를 절약 한 @Rod 에게 감사 합니다! rangeenumerate등등.


로 전환하면 대신 enumerate사용할 수 있습니다int(n)int(`x`[p])
Rod

7

펄, 43 바이트

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

온라인으로 사용해보십시오!

정규식은 정말 강력합니다.

설명

코드가 수행하는 첫 번째 작업은 via를 통해 입력으로 두 개의 정수를 읽고을 사용 <>하여 첫 번째에서 두 번째까지의 범위를 만듭니다 ... 그런 다음 표준 map함수를 사용하여이 범위를 반복하고 각 값에 다음 코드를 적용합니다 say if$_==eval s/./+$&**$+[0]/gr. 이것은 횡설수설처럼 보이지만 일종의 일이지만 실제로 일어나는 일이 있습니다.

map현재 값을 변수에 암시 적으로 저장합니다 $_. 많은 펄 함수와 오퍼레이션이 주어지지 않으면이 값을 사용합니다. 여기에는 s///대체 연산자 와 같은 정규식이 포함됩니다 .

대체 정규식에는 네 부분이 있습니다.

  1. 조작 할 문자열입니다. 일반적으로 연산자 =~는 문자열에 정규식을 적용하는 데 사용되지만이 연산자가 없으면 정규식은 암시 적 변수에 적용되며 함수 $_를 통해 현재 숫자가 포함 map됩니다.
  2. 검색 할 문자열입니다. 이 경우 와일드 카드로 표시되는 개행 문자가 아닌 단일 문자를 검색합니다 .. 실제로, 우리는 각 개별 숫자를 캡처합니다.
  3. 바꿀 문자열입니다. 우리는 더하기 기호를 대체하고 있습니다+ 수학 표현식을 모든 것을 훨씬 쉽게 만드는 마법의 Perl 변수와 혼합됩니다.

특수 스칼라 변수 $&에는 항상 마지막으로 성공한 정규식 캡처 (이 경우 단일 숫자)가 포함됩니다. 특수 배열 변수 @+에는 항상 마지막으로 성공한 일치에 대한 사후 일치 오프셋 목록이 포함됩니다 ( 예 : 일치 텍스트 색인) . 바로 뒤에 나오는 텍스트 $+[0]의 색인입니다 . 의 경우 , 우리는 숫자를 포착하고 텍스트 바로 뒤에있는 텍스트 의 인덱스 (즉, )는 1이며 이는 지수입니다. 그래서 우리는 (1)의 힘 을 높이고 싶습니다$_$&135113535$&$+[0] 얻습니다. 우리는 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,<>..<>
Dada

그리고 "@+"1 바이트보다 짧습니다 $+[0]:)
Dada

7

자바 스크립트 (ES7), 105 91 89 88 83 79 82 81 bytes

20B를 절약 한 Arnauld와 6B를 절약 한 ETHProductions에 감사드립니다!

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]

추가 골프

이것은 꽤 골프 해 보이지만 항상 개선의 여지가 있습니다.


예, 실제로는 약간 짧습니다. 감사!
Luke

1
2 바이트를 저장 d**(e+1)하도록 변경할 수 있습니다 d**-~e.
ETHproductions

팁 주셔서 감사합니다, 추가했습니다. 파이썬을
Luke

&대신 사용할 수 있습니다 &&. 갈 바이트 하나 더
Arnauld

방금 로컬 사본에서 변경했습니다.
Luke

6

자바 스크립트 (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 모든 브라우저에서 작동해야하므로.



5

파이썬 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 표준 규칙에 맞게 답변을 변경하는 것이 좋습니다
george

5
프로그램이 여전히 "작동"하고 출력 이 하드 코딩되지 않기 때문에 이것이 하드 코딩 규칙을 위반한다고 생각하지 않습니다 .
Alex Howansky

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)]

소요 이름 기능 nm. 항상 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 초 전에 그 결론에 도달했습니다. Thnx!
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

파이썬 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

그것은 나의 시도를 당신과 똑같이 만들 것입니다!
hashcode55

거의. 당신은 list('k')내가 가지고 있지 않습니다. 그러나 여전히 공백을 제거 할 수 있습니다 :)
Yytsi

3

파이썬 2 , 84 바이트

현재 람다 솔루션과 동일한 길이의 전체 프로그램 접근 방식입니다.

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

3

apt, 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

In the latest version of Japt, x accepts a function as an argument, which allows us to golf another byte:

òV f_¥Zì x@XpYÄ

Test it online!


2

Clojure, 107 bytes

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

Implementing the equation is terribly long.


can save a couple of bytes by doing (.pow(-(int v)48M)
cliffroot

2

TI-Basic, 85 bytes

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

I did not know hard-coding was permitted. :)
Abel Tom

@AbelTom Well, it really helps that this series only has 20 terms. Also, converting number to string in TI-Basic takes lots of bytes. Only other solution would be to int(log( every number and then do the powers. Perhaps this is shorter, but I doubt it.
Timtech

That input method is very clever but kind of sketchy. You need to be in FUNC mode and the window has to be set up to include your input point. Doesn't seem portable enough to me.
Jakob

@JakobCornell By default the calc is in FUNC mode, although I do see what you're saying about the input resolution. But, this method is pretty common in golfing. You could always Prompt X,Y instead.
Timtech

2

Haskell, 61 bytes

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

Usage example 5 # 600 -> [5,6,7,8,9,89,135,175,518,598].

Check each number i in the range [n..m]. The digits are extracted by turning i into a string (show) and making each char a one element string (pure) which is turned into an integer again (read). Zip those numbers element wise with [1..] via the function ^ and take the sum.


2

PHP, 92 91 88 bytes

3 bytes saved thanks @AlexHowansky

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

takes input from command line arguments; prints a trailing comma. Run with -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!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.