アナスタシアの世界では数学はどのように機能しますか?


44

バックグラウンド:

現実の世界での基本的な加算や乗算などの標準演算は、次のように機能します。

12 + 123 = 135

そして

12 * 123 = 1476

それは面白くて退屈ではありません!多くの学校では、これをすでに公式アルゴリズムの実践、実践、実践として解釈しています。これは、かなり厳格で退屈な数学的食事を意味し、この課題で意図されているものではありません。私たちの最愛のサイトでいくつかの楽しみをする準備をしてください。

2つの正の整数を追加し、その結果のすべての数字を再度追加するプロセスを検討してください。1桁のみが取得されるまで、追加を繰り返します。例えば:

  1. 結果12 + 123は135です。
  2. 135のすべての数字を追加して取得し1 + 3 + 5 = 9ます。

この繰り返し加算で1桁の値9を取得するために必要なステップ数は2です。

前の加算プロセスと同様に、2つの正の整数の乗算は同じプロセスに従います。結果のすべての数字を乗算し、1桁だけが残るまでこのプロセスを繰り返します。上記の例を見てください。

  1. 結果12 * 123は1476です。
  2. 取得する1476のすべての数字を乗算します1 * 4 * 7 * 6 = 168
  3. 168のすべての桁を再度乗算します1 * 6 * 8 = 48
  4. 取得し4 * 8 = 32た48のすべての桁を再度乗算します。
  5. 取得し3 * 2 = 6た32のすべての数字をもう一度乗算します。

この繰り返される乗算で1桁の値6を取得するために必要なステップ数は5です。

この挑戦の酒と数学表記の誤用を避けるために、私はこれらの2つのダミーの表記を導入:(+)そして(*)あなたはあなたが好きな表記を使用する以下のように、仕事を:

  1. 単一の値を取得するための繰り返し加算プロセスの操作は12 (+) 123 = 9です。
  2. 単一の値を取得するために繰り返される乗算プロセスの操作は12 (*) 123 = 6です。

チャレンジ:

課題は、実行可能なプログラムまたは機能のいずれか書くことにある操作の両方を背景技術の項で説明したように:(+)および(*)

入力:

プログラムまたは関数の入力は、2つの正の整数と1つの演算で、(+)とのいずれか(*)です。入力の形式は、プログラマーの任意の選択です。たとえば、入力をフォーマットするa (+) bか、F(a, (+), b)または任意のフォーマットを使用できます。

出力:

プログラムまたは関数の出力には、操作の結果と、必要に応じてフリースタイル形式で必要なステップ数が含まれている必要があります。

テストケース(入力および出力形式を無視):

    81 (+) 31       -->   (4 ; 2)
    351 (+) 14568   -->   (6 ; 3)
    21 (*) 111      -->   (8 ; 3)
    136 (*) 2356    -->   (0 ; 2)

一般的なルール:

  • これはであるため、バイト単位の最短回答が課題に勝ちます。
    esolangが通常の言語で回答を投稿することを妨げないようにしてください。プログラミング言語で可能な限り短い回答を提供することにより、この課題をお楽しみください。賢明な回答と明確な説明を投稿すると、使用するプログラミング言語に関係なく、回答が高く評価されます(したがって、賛成票になります)。
  • 回答には標準ルールが適用されるため、STDIN / STDOUT、適切なパラメーターを使用した関数/メソッド、完全なプログラムなどを使用できます。選択はユーザー次第です。
  • 可能であれば、プログラムは大きな数値を適切に処理できます。そうでない場合は、それで十分です。

ゲームを始めましょう!!


繰り返される追加部分(デジタルルート)は、本質的にcodegolf.stackexchange.com/q/1128/194の
ピーターテイラー

4
素晴らしい最初の質問!そして、私自身の質問から一般的なルールの形式と文章を認識しています。;)
ケビンクルーイッセン

4
@KevinCruijssenうん。そのとおり。それには著作権がないので、私はあなたの許可なしにそれを複製します。ふふふ:D
アナスタシア・-Romanova秀

4
@ Anastasiya-Romanova秀「著作権なし」?XXI世紀に?いや; ここにあるものはすべてCC-BY-SA 3.0です。コンテンツが送信されると、許可が付与されます。サイトのフッターを確認してください。
マインドウィン

1
@ BradGilbertb2gillsはい、もちろん。ちなみに投稿で述べられています。引用:「入力の形式はプログラマーの任意の選択です」。
アナスタシアロマノバ秀

回答:


11

Dyalog APL33 32 30 29 バイト

これにより、APLが拡張され、プレフィックス表記+/A n₁ n₂とが含まれます×/A n₁ n₂。(実際、の左側の任意の操作を使用でき/Aます。){result、repeat count}のリストを返します。

A←{(⊃,≢)⍺⍺{∪⍵,⍨⍺⍺⍎¨⍕⊃⍵}⍣≡⍺⍺⍵}

A←{左辺関数、および右辺引数の観点から高階関数を定義する⍺⍺

(⊃,≢) の最初の要素とそれに続くカウント

⍺⍺{高階関数に供給される提供された関数(+/和または×/積)

のユニークな要素

⍵,⍨ に追加される引数

⍺⍺ 与えられた関数

⍎¨ の各文字の評価

の文字表現

⊃⍵ 引数の最初の要素

}⍣≡ 結果が引数と同じになるまで繰り返し適用され、

⍺⍺⍵元の引数に適用された元の供給関数(+/または×/

} [高階関数定義の終わり]

TryAPLオンライン!(セキュリティ上の理由でエミュレートされていeます。)

バイトを保存してくれた@ngnに感謝します。


0バイト(jest内)

Dyalog APLは、実際にアナスタシヤンの数学を完全にサポートしています。(+)andの代わりにand (×)を使用+{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}ます。

試してみてください81 +{(⊃,≢)⍺⍺{∪⍵,⍨⍺⍺e¨⍕⊃⍵}⍣≡⍺⍺/⍺⍵} 3121 ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/e¨⍕⍵}⍣=⍵⍺⍺⍨⍺} 111


答えてくれてありがとう(+1)。多数の入力を処理できますか?
アナスタシアロマノバ秀

1
あなたが設定されている場合⎕FR←1287(つまり、IEEE 754-2008 128ビットの小数使用F loating点Rの epresentationを)と⎕PP←34(つまり、34文字の使用P RINT Pの recision)を、あなたは10³⁴下の整数を使用することができます。
アダム

うーん、それは完全にサポートしていますが+{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}まだかなりのバイトではありませんか?私はこれが0バイトであるかについて混乱しています..:S
ケビンCruijssen

3
@KevinCruijssen OPは任意の入力表記を許可します。したがって、言語がたまたまデフォルトのアナスタシヤン数学をサポートしている場合、マルチ文字グリフ(+)はアナスタシヤン+になります。Dyalog APLはAnastasiyanの数学をサポートしますが、異なるマルチ文字グリフを使用します。これはちょうど*パワーと×乗算が必要なことを/意味し、複製と÷分割が必要なことを意味します。
アダム

1
@Adámああ、それは理にかなっています。OPのルールを少し曲げていますが、それを壊していません。入力としてではなく、かなり奇妙なこと(+)です+{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}が、OPが実際に任意の入力形式で行うと述べているので、関数をパラメーターとして使用できます。うーん、入力として機能をサポートする他のプログラミング言語でもこれが可能かどうか疑問に思います。
ケビンCruijssen

8

Haskell、108バイト

f=map(read.pure).show
g h=(\x->(h.f$last x,length x+1)).takeWhile(>10).iterate(h.f)
(a#b)o=g(foldr1 o)$o a b

#最初に取り、次に演算子aとなる関数を定義します。楽しい事実:これは、任意の演算子(実際には、任意の関数)で機能します!bo


答えてくれてありがとう(+1)。多数の入力を処理できますか?
アナスタシアロマノバ秀

4
@ Anastasiya-Romanova秀はい、HaskellのIntegerタイプには制限がないため、RAMと同じ大きさの数値を処理できます。
ThreeFx

8

パイク、16バイト

RE`DltImbRoKr)oh

ここで試してみてください!

RE               - evaluate the input as Pyke code
                 -  (`B` is product and `s` is sum, the second line is a tuple)
  `              - i = str(^)
    ltI      )   - if len(i) != 1:
       mb        -   map(i, int)
         R       -   get the `B` or `s` from input
          oK     -   o++
            r    -   goto_start()
              oh - o++ + 1

として乗算しB、として加算しsます。2つの数値入力はコンマで区切られます。


1
いいね!説明をいただけますか?
エミグナ

答えてくれてありがとう(+1)。多数の入力を処理できますか?
アナスタシアロマノバ秀

@ Anastasiya-Romanova秀任意の番号を処理できるはずです
ブルー

両親のインターネット利用ポリシーに違反しているため、ウェブがブロックされているため、コードをテストできません。T_T
アナスタシア・ロマノバ秀

次のようなもの:Webページがブロックされました!インターネット使用ポリシーに違反しているWebページにアクセスしようとしました。URL:pyke.catbus.co.uk/?code=RE%60DltImbRoKr%29oh&input=B%0A21%2C+111&warnings=0カテゴリ:未評価
Anastasiya-Romanova秀

8

JavaScript(ES6)、59

再帰関数。入力形式は、再帰呼び出しを簡素化するように調整されています。

  • 演算子:「+」または「*」
  • オペランド:2つの値の配列
f=(o,v,s=1,t=eval(v.join(o)))=>t>9?f(o,[...t+''],s+1):[t,s]

テスト

f=(o,v,s=1,t=eval(v.join(o)))=>t>9?f(o,[...t+''],s+1):[t,s]

;[
  [81,'+',31,     /* -> */ 4, 2]
, [351,'+',14568, /* -> */ 6, 3]
, [21,'*',111,    /* -> */ 8, 3]
, [136,'*',2356,  /* -> */ 0, 2]
].forEach(t=>{
  var [a,o,b,k1,k2] = t,
      [r,s]=f(o,[a,b]);
  console.log(k1==r && k2==s ? 'OK':'KO',a,o,b,'->',r,s)
})  
  


答えてくれてありがとう(+1)。多数の入力を処理できますか?
アナスタシヤロマノバ秀

1
@ Anastasiya-Romanova秀javascript数値形式の制限まで、53ビットの精度(10進数17桁)
edc65

8

Python 2、60バイト

f=lambda s,c=0:s[1:]and f(min(s).join(`eval(s)`),c+1)or(s,c)

入力はのような文字列で81+31、出力はシングルトン文字列とカウンターのタプルです(例:('4', 2)

Ideoneでテストします。


入力を文字列の配列として受け入れ、単一の文字列を許可する場合、たとえば、f(['81', '31'],'+')さらにバイトを保存できますが、それは規則を少し広げすぎているように感じます
Dennis


...その場合、私は遠くまで行き、それぞれ通過するoperator.addか、またはoperator.mulそれぞれ検討するでしょう;)
トビアスキンツラー

7

Pyth、16

eJ.uvjhQ`N.vQ)lJ

"+ 123 12"加算や"* 123 12"乗算のような入力を受け取ります。のような出力result<linefeed>steps

ここ試してみるか、テストスイートを実行しますが、これはevalに依存しているため、追加のバリアントのみがオンラインインタープリターで機能することに注意してください。乗算は、オフラインインタープリターで正しく機能します。

これは、累積リダクション関数を使用して中間結果のリストを作成するため、"+ 351 14568"取得し[14919, 24, 6]ます。これは、1桁の数字がアナスタシアの加算および乗算の固定小数点であるため機能します。次に、配列の最後の要素と配列の長さを取得します。

これは、少なくともメモリが不足するまで、任意の大きな数に対して機能します。


7

R、175 167 164 140 134 127 126 119バイト

function(G,S,D){i=1;O=switch(S,"+"=sum,prod);x=O(G,D);while(x>9){i=i+1;x=O(strtoi(strsplit(paste(x),"")[[1]]))};c(x,i)}

アンゴルフド:

f=function(G,S,D) #The function takes : the left operand, the operation symbol (between quote marks)
                  #and then the right operand
i=1               #That's the counter

O=switch(S,"+"=sum,prod)     #`O` takes the value `sum` if `S` matches `+`, `prod` 
                             #(which is the next agument) if not. 

x=O(G,D)                     #Does the first operation

while(nchar(x)>1)                 #While the number of character of the result 
                                  #of the operation is not of length 1, i.e., an integer :

    i=i+1                                    #Increase the counter
    x=O(strtoi(strsplit(paste(x),"")[[1]]))  #Apply the operation `O` to the first operation and 
                                             #the eventual subsequent ones

c(x,i)                                 #Outputs the result and the counter

ifelse帰ってきた!うん!
いや

使用法 :

Special addition
> f(31,"+",81)
[1] 4 2

Special multiplication
> f(136,"*",2356)
[1] 0 2

24バイトのゴルフをしてくれた@plannapusに感謝します!@Vloからの良いアイデアのおかげで-7バイト!


はい、私はRが大好きなので説明を追加してください!これはVBAに続く私の第二言語です。(+1)
Anastasiya-Romanova秀

1
@ Anastasiya-Romanova秀:完了!
フレデリック

@plannapus:本当にいいね!どうもありがとう !
フレデリック

1
@Frédéricのいい使い方strtoi!あと4バイトでbeatられました。
プランナパス

1
最初の操作でxの割り当てにOの定義を含めることにより、バイトをさらにゴルフオフできるように見えます:x =(O = switch(S、sum、 `*`))(G、D);。
rturnbull

6

05AB1E20 15バイト

[¼¹iOëP}Dg#S]¾‚

説明

[       Dg# ]    # loop until number is single digit
 ¼               # increase counter
  ¹iO            # if operation is addition, sum list
     ëP}         # else take product of list
           S     # split into a list of digits
             ¾‚  # pair final number with counter and output

演算子は加算の場合は1、乗算の場合は0です。

オンラインで試す


答えてくれてありがとう(+1)。多数の入力を処理できますか?
アナスタシアロマノバ秀

@ Anastasiya-Romanova秀理由はわかりません。例はありますか?
エミグナ

あなたのプログラムはそのような入力に対してテストされているので、完璧です:)
アナスタシヤ-ロマノバ秀

6

ゼリー11 10 バイト

Dj⁹VµÐĿḊĖṪ

入力は数字のペアであり、+またはのいずれか×です。

オンラインでお試しください!または、すべてのテストケースを確認します

使い方

Dj⁹VµÐĿḊĖṪ  Main link. Left argument: [x, y] (integers). Right argument: + or ×

    µÐĿ     Repeatedly execute the chain to the left, initially with argument
            [x, y], then with the previous return value. Stop when the results are
            no longer unique, and return the array of all intermediate results.
D           Decimal; convert the integers [x, y] or the return value z to base 10.
 j⁹         Join, separating by the link's right argument, i.e., '+' or '×'.
   V        Evaluate the result. This casts the previous return value to string,
            so, e.g., [8, 1, '+', 3, 1] becomes "81+31" before evaluation.
       Ḋ    Dequeue; discard the first intermediate result, i.e., [x, y].
        Ė   Enumerate; prefix each integer in the array with its 1-based index.
         Ṫ  Tail; extract the last index-value pair.

6

ARMマシンコード、48バイト

六角ダンプ:

b570 2a00 bf0c 1840 4348 2101 230a e00c 3101 0015 fbb0 f6f3 fb06 0413 2a00 bf0c 192d 4365 0030 d1f5 0028 280a d2f0 bd70

この関数は、システムコールやライブラリ関数に依存しません。これはThumb-2コードで、32ビットARMの可変長命令エンコード(2または4バイト)です。したがって、処理できる最大値は2 ^ 32-1です。AAPCS(46バイト)に準拠していない場合、最初にレジスタをスタックする必要がないため、2バイトがドロップされる可能性があります。

ゴルフされていないアセンブリ(GNU構文):

.syntax unified
.text
.global anastasiya
.thumb_func
anastasiya:
    @Input:
    @r0 - First number
    @r1 - Second number
    @r2 - 0 for add, 1 for multiply
    @Output:
    @r0 - Resultant value
    @r1 - Number of steps
    push {r4,r5,r6,lr}
    cmp r2,#0
    ite eq @if r2==0
    addeq r0,r0,r1 @r0+=r1
    mulne r0,r0,r1 @else r0*=r1
    movs r1,#1 @r1 is the number of steps
    movs r3,#10
    b endloop
    loop:
        adds r1,r1,#1 @Increment number of steps
        movs r5,r2 @r5=1 if multiply, 0 if add
        parseDigits:
            udiv r6,r0,r3 @r6=r0/r3
            mls r4,r6,r3,r0 @r4=r0 - r6*r3
            @Last two operations were r4=r0%r3 (r3==10)
            cmp r2,#0
            ite eq @if r2==0
            addeq r5,r5,r4 @r5+=r4
            mulne r5,r5,r4 @else r5*=r4
            movs r0,r6 @r0=r6 (Set r0 to r0/10)
            bne parseDigits @while (r0!=0)
        @Now our new total is in r5
        movs r0,r5 @Put it in r0
    endloop:
        cmp r0,#10
        bhs loop @while (r0 >=10)
    pop {r4,r5,r6,pc} @Return

Cでのテストスクリプト:

#include <stdio.h>
unsigned long long anastasiya(unsigned,unsigned,unsigned);

int main(void) {
    unsigned x,y,op;
    printf("Enter first operand, second operand, and 0 for addition or 1 for multiplication.\n");
    scanf("%u%u%u",&x,&y,&op);
    unsigned long long res = anastasiya(x,y,op);
    printf("Result = %u, steps = %u\n",(unsigned)res ,(unsigned)(res >> 32));
}

4

R、130 124文字

@Frédéricとは多少異なるアプローチ:

f=function(a,f,b){b=c(a,b);n=1;while((m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)))>1){b=d%%10^(1:m)%/%10^(1:m-1);n=n+1};c(d,n)}

インデント、改行あり:

f=function(a,f,b){
    b=c(a,b) # Take both numbers
    n=1 #Counter
    while((m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)))>1){
#My own special digit splitter! (d is the result and m is the nb of char of d)
        b=d%%10^(1:m)%/%10^(1:m-1)
        n=n+1
    }
    c(d,n) #Print results
    }

行4には、おそらくさらに説明が必要です。

switch(f,'(+)'=sum,prod) #pick which operator to use
switch(f,'(+)'=sum,prod)(b) # apply it to b
d<-switch(f,'(+)'=sum,prod)(b) #Saves the result in d
nchar(d<-switch(f,'(+)'=sum,prod)(b))#Measures the number of character of d
m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)) #Saves it in m
(m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)))>1 #Checks if it is more than 1

テストケース:

> f(12,"(+)",123)
[1] 9 2
> f(12,"(*)",123)
[1] 6 5
> f(351,"(+)",14568)
[1] 6 3

あなたはこの答えに遅れて来たのは非常に残念ですが、あなたは私の賛成票を持っています。R.でこれを作成してくれてありがとう
アナスタシア・Romanova秀

なぜ不幸なのですか?
プランナパス

あなたが最初に来ていたなら、あなたはより多くの賛成票を持っているだろうから
アナスタシア・

@ Anastasiya-Romanova秀
まあまあです

f関数名とその引数の1つになることのボーナスポイント:)
JDL

4

オクターブ、85バイトMATLAB、123、114、105、94バイト

これをOctaceに変換して、直接インデックス付けと機能のインクリメントを活用することにしました。フォームの入力を受け取りますf(a,operator)。ここでa = [number1, number2]、およびoperator==1は積をoperator==2与え、合計を与えます。

function[x,i]=f(a,o)
g={@prod,@sum}{o};x=g(a);i=1;while(x=g(num2str(x)-48))>9;i++;end

説明:

g={@prod,@sum}{o} :適切な関数、製品、または合計を選択して割り当てます g

x=g(a) 入力の合計または積を取ります

i=1; ... i++ :歩数を数えるためのインクレメンター

while(x=g(num2str(x)-48))>9;
          num2str(x)-48)     % turns a number 123 into an array [1 2 3].
        g(num2str(x)-48))    % Takes the sum or product of the array
      x=g(num2str(x)-48))    % Assign that value to the variable x
      x=g(num2str(x)-48))>9  % Checks if x > 9, continue looping if yes

2つの改行、スペースを削除し、別々の引数ではなくベクトルに両方の入力番号を配置しました。これにより、pajonkのおかげで9バイトが節約されました!k=@(x)...ビーカー=)のおかげでさらに11バイトを節約するために削除されました最後に、さらに9バイトを節約するためにすべてをOctaveに変換しました...


4

Javaの、164の 159 146バイト

int[]p(int t,int m,String[]d){int r=m;for(String i:d){int x=Integer.decode(i);r=m<1?r+x:r*x;}return r>9?p(++t,m,(r+"").split("")):new int[]{r,t};}

最初の引数は単なるカウンターで、常に0です

2番目の引数はメソッドで、ADDの場合は0、MULTIPLYの場合は1です。

3番目の引数は、加算/乗算する値を含む文字列の配列です。

非ゴルフ

public static int[] p(int t, int m, String[] d) {
    int r = m;
    for (String i : d) {
        int x = Integer.decode(i);
        r = m < 1 ? r + x : r * x;
    }
    return (r + "").length() > 1 ? p(++t, m, (r + "").split("")) : new int[]{r, t};
}

数バイトをカットしてくれた@Kevin Cruijssenに感謝します。

5バイトを削る@milkに感謝します。

テストプログラム

public static final int ADD = 0;
public static final int MULTIPLY = 1;

public static void main(String[] args) {
    System.out.println(Arrays.toString(p(0, ADD, new String[]{"12", "123"}))); //9
    System.out.println(Arrays.toString(p(0, MULTIPLY, new String[]{"12", "123"}))); //6
}

public static int[] p(int t, int m, String[] d) {
    int r = m;
    for (String i : d) {
        int x = Integer.decode(i);
        r = m < 1 ? r + x : r * x;
    }
    return (r + "").length() > 1 ? p(++t, m, (r + "").split("")) : new int[]{r, t};
}

いいね、私のJavaの答えよりも短い。しかし、あなたも...現在、あなたの答えから欠落している答えと同様の手順を印刷することになっている
ケビンCruijssen

@KevinCruijssenああ。それは退屈だ..私は今それを修正しようとします。
ショーンワイルド

ところで、あなたはあなたの現在の答えを少しゴルフすることができます。m==0することができm<1Integer.parseIntできますInteger.decode
ケビンCruijssen

私はJavaをあまり使いませんがj、最後にその変数が必要ですか?インライン化を(r+"")2回行うと、数バイト削るように見えます。
ミルク

1
今後投稿を変更できませんか?編集を提案する場合は、コメントで提案してください。
ショーンワイルド

3

ゼリー、17バイト

+×⁵?µDSP⁵?$ÐĿµL;Ṫ

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

のような引数が与えられた場合x y 1、これはアナスタシヤ合計を計算しx (+) yます。

のような引数が与えられるとx y 0、これはアナスタシヤ積を計算しますx (*) y

出力はとして与えられます[number of steps, result]


答えてくれてありがとう、しかしプログラムの出力には必要なステップ数が含まれていませんか?ここに何かが足りませんか?
アナスタシアロマノバ秀

3

Python、160 146 129バイト

def r(s):
 n=str(eval(s));c=0
 while n[1:]:exec("n=str(reduce(lambda a,b:a%sb,map(int,list(n))))"%"*+"["+"in s]);c+=1
 return n,c

説明をすぐに投稿します。

入力は12+12or 5*35(通常の記号+*記号)の形式であり、これらが2つの演算子のみであると想定しています。

お使いのコンピューターのメモリが許す限り大きな数値入力を処理できます。

私は、これがさらに大きくなることをほぼ確実に確信しています。

編集: @Copperのおかげで16 31バイトが節約されました。


答えてくれてありがとう(+1)。多数の入力を処理できますか?
アナスタシヤロマノバ秀

@ Anastasiya-Romanova秀うーん...私は彼らができると確信しています。大規模な入力の例を教えてください。それらから計算してみます。
clismique

たぶん:3218753647208435810122106 * 29349566754?
アナスタシアロマノバ秀

1
@ Anastasiya-Romanova秀ええ、〜0.5秒で動作しましたが、適切に時間を計りませんでした。
clismique

に変更して"+" if "+" in s else "*"から"*+"["+"in s]、に割り当てる代わりtに、exec呼び出しでインラインに追加するだけです。

3

R、110バイト

@plannapus 'スプリッターを使用します。

function(A,F,B){r=Reduce;x=r(F,A,B);y=1;while(x>9){m=nchar(x);x=r(F,x%%10^(1:m)%/%10^(1:m-1));y=y+1};cat(x,y)}

f=function(A,F,B){
  r=Reduce                                  # Shortcut for Reduce
  x=r(F,A,B)                                # A operator B
  y=1                                       # Initiate counter
  while(x>9)                                # If number of digits > 2, or number > 9
  {m=nchar(x)                               # Count number of digits
    x=r(F,x%%10^(1:m)%/%10^(1:m-1))         # @plannapus's splitter, then feed into the A operator B operator C, etc while condition true
    y=y+1}                                  # Increment counter
  cat(x,y)}                                 # Print

出力

> f(136,"*",2356)
0 2
> f(31,"+",81)
4 2
> f(2,"+",3)
5 1
> (function(A,F,B){r=Reduce;x=r(F,A,B);y=1;while(x>9){m=nchar(x);x=r(F,x%%10^(1:m)%/%10^(1:m-1));y=y+1};cat(x,y)})(21,"*",111)
8 3

編集:私は数えられない。


Rが素晴らしいのは、ゴルフで価値のある機能を短縮できるからです。(+1)
アナスタシヤロマノバ秀

3

Clojure 126バイト

(defn f [o a b] (loop [n (o a b) c 1] (if (< n 10) [n c] (recur (reduce #(o %1 %2) (map #(- (int %) 48) (str n))) (inc c)))))

関数は次のように呼び出されます。

(f + 81 31)

コードは次のとおりです。

(defn f [o a b]
  (loop [n (o a b) c 1]
    (if (< n 10)
      [n c]
      (recur (reduce #(o %1 %2)
                     (map #(- (int %) 48) (str n)))
             (inc c)))))

(def test-cases [[+ 81 31]
                 [+ 351 14568]
                 [* 21 111]
                 [* 136 2356]])

(map #(apply f %) test-cases)
;;=> ([4 2] [6 3] [8 3] [0 2])

Clojureは私にとってまだ新しいので、これはおそらく最良の解決策ではないことに留意してください。挑戦はすべて楽しかったです。さらに、コードは非常に大きな数で問題なく実行されました。


これは非常に遅いですが、そこにあるスペースのほとんどを減らすことができます。
clismique

2

Perl 6 53バイト

{$/=(&^b($^a,$^c),{[[&b]] .comb}...10>*);$/[*-1],+$/}

以来( 12, &[+], 123 )入力のために許容され、私は53バイトにそれを得ることができます。
&[+]短縮形&infix:<+>は数値中置加算演算子に対する「敬意」です)

2番目の引数を文字列(+)にする必要がある場合、87バイトになります

{my&b=::("&infix:<$^b.substr(1,1)>");$/=(b($^a,$^c),{[[&b]] .comb}...10>*);$/[*-1],+$/}

説明:

# bare block lambda with 3 parameters declared using placeholder syntax
{
  # store list into 「$/」
  # ( used 「$/」 so that I don't have to declare a variable )
  $/ = (

    # declare second placeholder parameter, and call it
    &^b(
      # with the first and third placeholder parameters
      $^a, $^c
    ),

    # bare block lambda with implicit parameter 「$_」
    {
      # list reduce using the second parameter from outer block
      [[&b]]

      # a list of the digits of 「$_」 (implicit method call)
      .comb
    }

    # keep doing that until
    ...

    # it produces something smaller than 10
    # ( Whatever lambda )
    10 > *
  );

  # returns

  # final result ( last value from list )
  $/[ * - 1 ],
  # and count of values in list
  +$/
}

テスト:

#! /usr/bin/env perl6
use v6.c;
use Test;

my &anastasiya-math = {$/=(&^b($^a,$^c),{[[&b]] .comb}...10>*);$/[*-1],+$/}

my @test = (
  (  81, &[+], 31    ) => (4, 2),
  ( 351, &[+], 14568 ) => (6, 3),
  (  21, &[*], 111   ) => (8, 3),
  ( 136, &[*], 2356  ) => (0, 2),
);

plan +@test;

for @test -> $_ ( :key(@input), :value(@expected) ) {
  cmp-ok anastasiya-math(|@input), &[»==«], @expected;
}

通常の使用法:

# override built-in Bag operator 「(+)」 in current lexical scope
my &infix:<(+)> = &anastasiya-math.assuming: *, &[+], *;

# add a new operator
my &infix:<(*)> = &anastasiya-math.assuming: *, &[*], *;

say 12 (+) 123; # (9 2)
say 12 (*) 123; # (6 5)

2

Python 2、107 97バイト

g=lambda x,o,i=1:x<10and[x,i]or g(eval(o.join(`x`)),o,i+1)
lambda a,o,b:g(eval('%s'*3%(a,o,b)),o)

第1オペランドa、演算子o'+'または'*')、および第2オペランドの引数を介して入力を受け取り、次bの形式のリストを返す無名関数[result, steps]

使い方

無名関数は、オペランドと演算子を連結して文字列を作成し、評価します。これは質問で説明されている最初のステップです。次に、この値と演算子が再帰関数に渡されますg。ここでは、i再帰呼び出しごとに増分されるcounter が使用されます。入力が未満の場合10、1桁に達している必要があるため、これiが返されます。そうでない場合、入力は文字列に変換され、この文字列内の各文字が演算子と結合されて、目的の計算が行われ、評価されて再帰的に関数に渡されます。

Ideoneでお試しください


(+1)説明を待っている間:)
Anastasiya-Romanova秀

2

Groovy、102バイト

def p,e,r;p={t,m,d->e=d*.toInteger();r=m<1?e.sum():e.inject{a,b->a*b};r>9?p(++t,m,""+r as List):[r,t]}

デゴルフド

def p,e,r
p = { t, m, d ->
    e = d*.toInteger()
    r = (
            m<1
                ? e.sum()
                : e.inject { a, b -> a * b }
        )
    r > 9
        ? p(++t, m, "" + r as List)
        : [r,t]
}

説明

@Sean BeanのJava用の優れたソリューションに基づいています。

  • p:ソリューションを実装するクロージャー(関数、ラムダなど)
  • t:現在の呼び出しの深さ(反復回数)、p常にt=1
  • m:実行する操作、0「追加」、1「乗算」
  • d:オペランドのリスト。各オペランドはStringオブジェクトです
  • e:の要素はd、それぞれ整数に変換されます
  • re操作に応じたの合計または積m
  • で始まる結果ステートメントr > 9
    • 複数桁の場合(r > 9)、再度呼び出して、深さtを増やし、r数字文字列のリストに変換します(結果を返します)。
    • 一桁、リターンの場合rtリストなど。

テストプログラム

final ADD = 0
final MULTIPLY = 1
println p(1, ADD, ["12", "123"]) //9, 2
println p(1, MULTIPLY, ["12", "123"]) //6, 5
println p(1, ADD, ["2", "3"]) //5, 1

結果

[9, 2]
[6, 5]
[5, 1]

2

Haskell、76 70バイト

 (x#y)f=until(<[10])(\[s,i]->[foldr(f.read.pure)0$show s,i+1])[f x y,1]

結果とステップ数を含む2要素リストを返します。任意の大きな数で動作します。使用例:(351#14568)(+)-> [6,3]

編集:6バイトの@BlackCapに感謝します。


あなたは置き換えることができ(-48+).fromEnumread.pure
BlackCap

2

R、91バイト

@plannapusのスプリッターを使用する@Vloのコードと、@Frédéricの回答をゴルフでプレイ中に生成したいくつかのアイデアを使用して、これはまだ最短のR回答です。(今日ここに異常に多数のRが答えています...)

function(A,F,B){x=F(A,B);while(x>9){m=nchar(x);x=F(x%%10^(1:m)%/%10^(1:m-1));T=T+1};c(x,T)}

重要なのは、オペレーターの入力sumが(+)またはprod(*)のいずれかであることが必要なことです。チャレンジのルールでは、これは大丈夫のようです。

インデント付き:

function(A,F,B){
  x=F(A,B);
  while(x>9){
    m=nchar(x);
    x=F(x%%10^(1:m)%/%10^(1:m-1));
    T=T+1
  };
  c(x,T)
}

@Vloの答えとの主な違いは次のとおりです。

  1. を使用する代わりにReduce、関数である入力引数に依存し、単に明示的に呼び出します。(関数がファーストクラスのオブジェクトであることは間違いありません!)
  2. カウンターとして新しい変数を初期化する代わりに、Rのビルトインを使用しT、評価するTRUE(別名1)を使用しますが、これは予約変数ではないため、変更できます。したがってT+Tです2。それをカウンターとして使用します。
  3. cat出力を行う代わりに、でベクトルとして返しcます。2バイトを保存するだけでなく、出力がベクトルに強制されるという事実によりT、クラスが確実にクラスになりnumericます。を使用しcatTインクリメントされていない場合、のような誤った出力が得られます1 TRUE

while次のようにループを再構築し、F名前の競合を回避するために別のループに変更できますfunction(A,O,B){x=O(A,B);while({F=F+1;x>9})x=O(x%/%10^(1:nchar(x)-1)%%10;c(x,F)}}。ここ数年で思いつくRゴルフのトリックの数は驚くべきことだ。)
ジュゼッペ

@ジュゼッペニース再編!現時点ではメタコンセンサスを見つけることができませんが、関数内でTand Fカウンタートリックを使用することは実際には無効であると確信しています。したがってrm(T)、最後に明示がない限り、この答え(および他のいくつかの!)は無効です。メタ投稿を探し続けるので、夢を見ただけではなかったと確信できます。
rturnbull

Tand Fトリックは、変更しない限り、TまたはFグローバル環境で完全に有効であると信じています。たとえば、f=function(){T=T+1;T}一貫してを返します2。私が思うに、これはあなたが参照したメタポストです。
ジュゼッペ

@Giuseppe Ahはい、あなたは両方の点で正しいです。ありがとう!
rturnbull

1

Ruby、55バイト

再帰呼び出し。以前は@ edc65のJavaScriptの回答とは非常に異なっていましたが、最適化すると、最終的には回答からほとんど独立して開発された直接ポートになりました。 、バイトカウントを超えることができました。

入力は、演算子を表す文字列、およびオペランドを含む配列です。

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

f=->o,x,i=1{y=eval x*o;y>9?f[o,y.to_s.chars,i+1]:[y,i]}

結果は正しいですが、1桁の値を取得するために必要なステップの数は正しくありません。コードを修正していただけますか?
アナスタシヤロマノバ秀

@ Anastasiya-Romanova秀あ、そうですね。私の古いロジックでは、それを開始する必要i=0があり、リファクタリング時に忘れていました。
バリューインク

1

Perl、38バイト

+2を含む -ap

STDINの入力と演算子の周りのスペースを使用して実行します。

amath.pl <<< "12 + 123"
amath.pl <<< "12 * 123"

出力は数字とステップで区切られます +A

amath.pl

#!/usr/bin/perl -ap
1while++$\,$_=eval."+A",s/\B/$F[1]/g

ステップを単項で出力しても問題ない場合、この35バイトバージョンはより適切に動作します。

#!/usr/bin/perl -lap
1while$\.=1,$_=eval,s/\B/$F[1]/g

1

Mathematica、105 94バイト

コード。

{x,y}=(c=0;f//.a_:>(c++;t=o@@IntegerDigits@a);{t,c})&/.{{f->#1+#2,o->Plus},{f->#1#2,o->Times}}

使用法。

x[81, 31]
(* {4, 2} *)

x[351, 14568]
(* {6, 3} *)

y[21, 111]
(* {8, 3} *)

y[136, 2356]
(* {0, 2} *)

説明。

二つの関数xと((+)の場合)y((*)の場合)のパラメータを置き換えることによって同時に作成されるfo

(c = 0;
 f //. a_ :> (c++; t = o@@ IntegerDigits@a);
 {t, c}
)&

適切な値で。以下の場合xfとなり#1 + #2oなりPlus、のためにy、それらはそれぞれとに#1 #2なりTimesます。x説明の最後の部分の関数を書き換えます。

x = (
  c = 0;
  #1 + #2 //. a_ :> (c++; t = Plus@@IntegerDigits@a); 
  {t, c}
) &;

(* The symbol //. stands for ReplaceRepeated. 
   The rule a_ :> (c++; t = Plus@@IntegerDigits@a) is applied until the result no longer 
changed. Specifically, the rule increments the counter of 1 at each step (this is c++), 
then takes the sum of the digits of the previous result (this is Plus@@IntegerDigits@a). 
The rule stops to apply when the variable t is less than 10. We return the final result and 
the number of steps with {t, c}. *)

1

Java 7、203 195 192バイト

int c=1;String c(long a,long b,int o){return p(((o<1?a+b:a*b)+"",o)+","+c;}long p(String n,int o){long x=o,q;for(String s:n.split("")){q=new Long(s);x=o<1?x+q:x*q}c++;return x<10?x:p(x+"",o);}

これは、使用long(2の最大値は63 -1)。int代わりに(2 31 -1の最大値)を使用する場合、1バイト少なくなります(191バイト):

int c=1;String c(int a,int b,int o){return p(((o<1?a+b:a*b)+"",o)+","+c;}int p(String n,int o){int x=o,q;for(String s:n.split("")){q=new Integer(s);x=o<1?x+q:x*q}c++;return x<10?x:p(x+"",o);}

それはおそらくもう少しゴルフすることができます。..かかわらず、手順を印刷しただけでなく、両方の演算子のための答えは、いくつかのバイトを取る
0(のために使用します(+))と1(のために(*))。

未ゴルフ&テストコード:

ここで試してみてください。

class Main{
  static int c = 1;
  static String c(long a, long b, int o){
    return p((o < 1 ? a+b : a*b) + "", o) + "," + c;
  }

  static long p(String n, int o){
    long x = o,
         q;
    for(String s : n.split("")){
      q = new Long(s);
      x = o < 1
           ? x + q
           : x * q;
    }
    c++;
    return x < 10
            ? x
            : p(x+"", o);
  }

  public static void main(String[] a){
    System.out.println(c(81, 31, true));
    c = 1;
    System.out.println(c(351, 14568, true));
    c = 1;
    System.out.println(c(21, 111, false));
    c = 1;
    System.out.println(c(136, 2356, false));
  }
}

出力:

4,2
6,3
8,3
0,2
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.