二ナトリウムのジレンマ


31

二ナトリウムのジレンマ

Disariumは、次の番号として定義されます。

それぞれの位置で累乗された数字の合計は、元の数字と等しい


あなたのタスク

あなたは、二ナトリウムとして分類された数字に奇妙な強迫観念を抱いています。disariumの方法に従う必要性は非常に大きいため、特定の本の非disarium以外のページを読むことを拒否します。次の2つの持っているBIGの問題を:

  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ますか?非常に大きな二ナトリウム(12157692622039623539)がありますが、答えはそれを識別できるはずですか?
リン

@Lynnすでに多くの解決策があることを考えると、範囲に制限はないはずです。
CraigR8806

2
@リン。22桁を超える二ナトリウムは存在しないため、ある意味で範囲はすでに制限されています。
マッド物理学者

3
@MistahFiggins質問の下部にあるOEISリンクにアクセスしてください。Disariumシーケンスが実際に有限であることを示す証拠があります。
CraigR8806

回答:


11

Perl 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


に切り替えenumerateint(n)代わりに使用できますint(`x`[p])
ロッド

7

Perl、43バイト

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

オンラインでお試しください!

正規表現は本当に強力です、皆さん。

説明

コードが最初に行うことは<>、を介して入力として2つの整数を読み取り、で最初から2番目の範囲を作成し..ます。次に、標準map関数を使用してこの範囲を反復処理し、次のコードを各値に適用します。say if$_==eval s/./+$&**$+[0]/gr。これは意味がわからないように見えますが、それは一種のことですが、実際に起こっていることは次のとおりです。

map現在の値を暗黙的に変数に格納します$_。多くのperl関数と操作は、何も指定されていないときにこの値を使用します。これには、s///置換演算子などの正規表現が含まれます。

置換正規表現には4つの部分があります。

  1. 操作する文字列。通常、演算子=~は文字列に正規表現を適用するために使用されますが、この演算子が存在しない場合$_map関数を介して現在の番号を含む暗黙的な変数に正規表現が適用されます。
  2. 検索する文字列。この場合、ワイルドカードで示されている単一の非改行文字を検索しています.。実際には、個々の数字をキャプチャしています。
  3. 置換する文字列。プラス記号の+後に数学式を代入し、すべてを非常に簡単にする魔法のPerl変数と組み合わせています。

特殊なスカラー変数に$&は、最後に成功した正規表現のキャプチャ全体が常に含まれます。この場合、これは1桁です。特別な配列変数には、最後に成功した一致の一致後オフセットの@+リスト、つまり一致のテキストのインデックスが常に含まれます。 は、直後のテキストのインデックスです。の場合、数字をキャプチャし、直後のテキストのインデックス(つまり、)は1であり、これが指数です。したがって、(1)の(1)を累乗して1を取得します。3の2の累乗と9を取得します。5の3の累乗と125を取得します。$+[0]$_$&135113535$&$+[0]

入力がの135場合、結果の文字列は+1**1+3**2+5**3です。

  1. 正規表現変更フラグ。ここでは、2つの正規表現フラグを使用している- /g/r/g最初のものが見つかった後、置換を続行するようにインタープリターに指示します(そうでなければ、結果はになり+1**135ます)。/rインタプリタに、元の文字列を変更せず、代わりに置換後の文字列を返すように指示します。そうしないと上書きされるため、これは重要$_です。比較のために必要です。

置換がすべて完了すると、eval関数で評価される数式が取得されます。 +1**1+3**2+5**3はに評価され1 + 9 + 125 = 135、元の数と比較され135ます。これら2つは等しいため、コードは数値を出力します。


美しいソリューション。(最初の入力が0である場合、これは機能しませんが、それが重要かどうかはわかりません)。ゴルフに数バイト:map$_-eval s/./+$&**$+[0]/gr||say,<>..<>
ダダ

そして"@+"$+[0]:) より1バイト短い
ダダ

7

JavaScript(ES7)、105 91 89 88 83 79 82 81バイト

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]

さらにゴルフ

これはかなりよくできているように見えますが、改善の余地は常にあると思います。


ええ、実際はかなり短いです。ありがとう!
ルーク

1
に変更d**(e+1)d**-~eて、2バイトを保存できます。
ETHproductions

ヒントをありがとう、それを追加しました。Pythonを倒すまでにあと2バイトしかありません
ルーク

&代わりに使用できます&&。どこへ行くもう一つのバイト...
アルノー

ローカルコピーでそれを変更しました。
ルーク

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のDeveloper Editionで動作しますこのページからダウンロードできます。Firefoxの以前のバージョンは**演算子をサポートしておらず、他のブラウザは[for(a of b)c]構文をサポートしていません。

テストスニペット

これは.map、配列内包のMath.pow代わりにとの代わりに**使用するため、ES6をサポートするすべてのブラウザーで動作するはずです。



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
プログラムはまだ「動作」しており、出力はハードコーディングされていないため、これはハードコーディング規則に違反するとは思わない。
アレックスハワンスキー

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⁼、2つのリンクを1つに結合することです。
マイル

約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
イッツィー

それは私の試みをあなたのものと全く同じにするでしょう!
hashcode55

ほぼ。あなたが持っているlist('k')、私は持っていない。ただし、空白は引き続き削除できます:)
Yytsi

3

Python 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。
イッツィー

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(すべての番号に対して行われ、それから力を発揮します。おそらくこれは短いですが、私はそれを疑います。
ティムテック

その入力方法は非常に賢いですが、ちょっと大雑把です。FUNCモードにする必要があり、入力ポイントを含めるようにウィンドウを設定する必要があります。私には十分な移植性がないようです。
ヤコブ

@JakobCornellデフォルトでは、計算はFUNCモードになっていますが、入力解像度についてあなたが言っていることはわかります。しかし、この方法はゴルフではかなり一般的です。Prompt X,Y代わりにいつでもできます。
ティムテック

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)に変換され、各文字が1要素文字列(pure)に変換されて、再び整数に変換されます()によって抽出されreadます。[1..]関数を使用して、これらの数値を要素ごとに圧縮します^を使用を取得しsumます。


2

PHP、 92 91 88バイト

@AlexHowanskyのおかげで3バイト節約

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

コマンドライン引数から入力を受け取ります。末尾のコンマを出力します。で実行し-rます。


1
3つを保存for([,$n,$m]=$argv;$n<=$m;
アレックスハワンスキー

奇妙なことに、印刷は機能しますが、エコーは機能しません。エコーは何も返さないのだと思います-奇妙なことにnullでさえありません。
アレックスハワンスキー

@AlexHowansky:奇妙なことですが"$n"[index]"_$n"[index]解析エラーが発生し"89"[index]$s="$n";$s[index]完全に問題ありません。
タイタス

うーん、それは最初は奇妙に思えますが、ドキュメントをチェックした後、彼らはこの機能が文字列リテラルに対してのみ機能すると明示的に言っているようです。
アレックスハワンスキー

これは上手くいきますが、おそらくあなたには何のバイトも保存しません:("_$n")[index]
アレックスハワンスキー

2

Mathematica、59バイト

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

2つの整数引数を取り、整数のリストを返す名前のない関数。(d=IntegerDigits@#)^Range@Length@d適切な累乗数の数字のリストを作成します。Tr[...]==#これらの桁の累乗の合計が元の数値と等しいかどうかを検出します。


2

MATLAB、88 73バイト

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

元の回答:

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

num2str(n)-'0'n、aをその数字のベクトルに分割します。これ1:floor(log10(n))+1は、1の桁数の1を保持するベクトルnです。15バイトを節約する匿名関数にゴルフのログ記録してくれてありがとう。



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.