効率的なカウント


35

私が子供だったとき、私の貯金でドル札を数えたいとき、私は大声で数えたでしょう

1、2、3、4、5、6、7、8、9、10。
11、12、13、14、15、16、17、18、19、20。
21、22、23、24、25 ...

最終的に、これらの複数音節の数字の発音にうんざりしました。数学的に気にかけて、より効率的なカウント方法を作成しました。

1、2、3、4、5、6、7、8、9、10。
1、2、3、4、5、6、7、8、9、20;
1、2、3、4、5、6、7、8、9、30 ...

ご覧のとおり、前の番号から変更された数字のみを発音します。これには、数字の英語名よりもはるかに反復性が高いという利点があり、計算に必要な頭脳が少なくてすみます。

チャレンジ

正の整数を取り、それをカウントする方法を出力/返すプログラム/関数を作成します。つまり、右端のゼロ以外の数字とすべての後続ゼロです。

   1    1
   2    2
  10   10
  11    1
  29    9
  30   30
  99    9
 100  100
 119    9
 120   20
 200  200
 409    9
1020   20

テストケースの完全なリストは必要ないはずです。これは、OEIS上のA274206です。

ルール

  • エントリは、精度とメモリの問題を無視して、理論的にはすべての正の整数で機能する必要があります。
  • 入力と出力は10進数でなければなりません。
  • 入力または出力を数値、文字列、または数字の配列として選択できます。
  • 入力は正の整数であることが保証されています。エントリは無効な入力に対して何でもできます。

これはであるため、バイト単位の最短コードが優先されます。


「10進数で」には、最後のテストケースの[1,0,2,0]->のような10進数のリストが含まれ[2,0]ますか?(「単一項目配列」という語句については不明です)。
ジョナサンアラン

1
@JonathanAllan「単一項目配列」とは、整数を表す単一の数値または文字列を含む配列を意味します。数字の配列を許可することは良い考えだとは思いませんでしたが、文字列が許可されているため(そして、文字列は多くの言語の配列に非常に似ています)、今では一種の任意の制限のようです。したがって、正当な理由がない限り、数字の配列を許可します。
ETHproductions

5
それをやった、あなたは私の秘密を盗んだ:P
LegionMammal978

1
ほとんどの人は子供のようにこのように数えていると思います。;)少なくとも私もそうしました。:)
ケビンクルーイッセン

7
@KevinCruijssen「子供の頃」?
マーティンエンダー

回答:



11

ゼリー6 3 バイト

数字の10進数リストとしてI / Oを使用することにより、-3バイト。

ṫTṪ

オンライン試す

どうやって?

ṫTṪ - Main link: listOfDigits  e.g.  [1,    0,    2,    0]  or [1,      1,    9  ]
 T  - truthy indexes                 [1,          3      ]     [1,      2,    3  ]
ṫ   - tail (vectorises)              [[1,0,2,0],  [2,0]  ]     [[1,1,9],[1,9],[9]]
  Ṫ - tail pop                                    [2,0]                       [9]

10進リストを取得できなかった場合、6バイトは次のようになります。

DµṫTṪḌ

ここで見ることができます

これは同じことを行いますが、事前に整数を10進数リストに変換し、その後整数に戻します。


最初のいくつかの答えをスクロールしていたとき、「3バイトのゼリーソリューションがあるに
違い

9

C、30 29 27バイト

これを誇りに思って、2つのCエクスプロイトを悪用してこれをゴルフします(投稿の最後で説明)。これは特にC(GCC)向けです


3)b=10;f(a){a=a%b?:b*f(a/b);}// 27バイト

2)b;f(a){b=a=a%10?:10*f(a/10);}// 29バイト

1)f(i){return i%10?:10*f(i/10);}// 30バイト

オンラインで試す(27バイトバージョン)


最初の試行(30バイト):GCCでは、3項で値が宣言されていない場合、条件値が返されるという事実を悪用します。したがって、真の戻り値が3項演算子であるのはなぜですか。

2回目の試行(29バイト):GCCのメモリバグを悪用します。ここで理解している限り、関数に戻り値がない場合、関数で2つ以上の変数が有意に利用されている場合、最初の引数変数の最後の設定値返されます。
   (編集:ただし、この「値の設定」は特定の方法で設定する必要があります。たとえば、変数を設定する、=または+=機能するが、設定すると%=機能しない、奇妙なことです)

3回目の試行(27バイト):上記のメモリバグを適切に悪用するには、2番目の変数(b)を有意義に使用する必要があるため、「10」の実際の変数として使用することもできます。
   (注:私はスワップすることができるはずa=a%ba%=b、別のバイトを保存するが、残念ながら、これはメモリバグが「作業」停留所に上記のエクスプロイトなり、私はできませんので)


回答のタイトルに「GCC」を追加することもできます。これは、GCC固有であるためです(clangでは機能しません)。また、「メモリバグ」は、おそらくGCCが使用する特定のスタックフレームレイアウトが原因で機能する、未定義の動作である可能性があります。GCCを使用しても、おそらく他のプラットフォームでは機能しません。
サイモン

@gurka完了、ありがとう
アルバートレンショー

7

網膜7 6バイト

!`.0*$

オンラインで試す(すべてのテストケース)

入力文字列の末尾にゼロが続く数字の出力一致。必須ではありませんが、これもたまたま動作し0ます。


ええと、代わりにが必要だと思っていました[1-9](または[^0]\d。私はその貪欲さが*毎回正しい出力を保証すると思います。
ETHproductions

@ETHproductionsこれは貪欲とは関係ありません*が、一致が左から右に検索されるという事実とは関係ありません。\d0*?$また動作します。
マーティンエンダー

正規表現を使用して.0*$動作するはずです
12Me21

出力する(十分に短い)の方法は、唯一の最後のマッチがある場合、あなたは使用することができます.0*
12Me21

@ 12Me21これを行う唯一の方法は、最後の出現のみを一致させるか、replaceまたは何かを使用することです。短くなりません。
mbomb007

7

Cubix、18 32バイト

後でこれに時間を費やし、少し圧縮できるかどうかを確認する必要があると思います。しかし、今のところはそうです。
私はこれについて全く間違った方法で考えていたことがわかりました。これで、プロセスはmod(1,10,100,1000、...)を入力整数に増分的に適用し、ゼロでない最初の整数を出力します。もう少し退屈ですが、短いです。

!N%*I1^\.u;u@O\;;r

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

    ! N
    % *
I 1 ^ \ . u ; u
@ O \ ; ; r . .
    . .
    . .

Cubixの答えを見るのはいつもいいです:)
オリバー

@obarakonすぐに我慢できる改良版を手に入れました。本当にこの1間違った方法でした
MickyT


5

Javascript 19 18バイト

1バイトのゴルフをするETHproductionsと2バイトのゴルフをするPatrick Robertsに感謝します

x=>x.match`.0*$`

入力文字列の末尾にある正規表現に一致する文字列の配列を返します。任意の文字の後に最大数のゼロが続きます。

オンラインで試す


5
g見つける必要のあるマッチは1つしかないため、が必要だとは思わない。
ETHproductions

使用して2バイト節約x=>x.match`.0*$`
パトリックロバーツ



3

Brachylog、2バイト

a₁

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

a₁整数の接尾辞builtin は、次のように実装されます。

brachylog_adfix('integer':1, 'integer':0, 'integer':0).
brachylog_adfix('integer':1, 'integer':I, 'integer':P) :-
    H #\= 0,
    H2 #\= 0,
    abs(P) #=< abs(I),
    integer_value('integer':Sign:[H|T], I),
    integer_value('integer':Sign:[H2|T2], P),
    brachylog_adfix('integer':1, [H|T], [H2|T2]).

Brachylogは、整数を数字のリストとして扱うことができることを好み、そのためにカスタムユーティリティpredicateを使用しますinteger_value/2。ここで興味深いのinteger_value/2は、先行ゼロ付きの数字リストを正しく変換できる必要があるため、整数を先行ゼロ付きの数字リストに変換できるようになるため、それを望まない述語(ほとんどの場合、特にのようなnondetの場合a)は、数字リストの先頭が0になることを禁止します。したがって、a₁リストと文字列に対して最初に最短のサフィックスを生成しますが、重複の除去に加えて、生成された最初の接尾辞が、最後にゼロが付いた右端のゼロ以外の数字であることも意味します。


2

Brain-Flak、74バイト

{({}<>)<>}(()){{}<>(({}<>)[((((()()()){}){}){}){}]<(())>){((<{}{}>))}{}}{}

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

最後の0以外とすべての後続の0のみを出力します。

説明:

{({}<>)<>}                    # Move everything to the other stack (reverse the input)
(())                          # Push a 1 to get started
{                             # do...
  {}<>                        #   pop the result of the equals check (or initial 1)
  (                           #   push...
    ({}<>)                    #     the top value from the other stack (also put this on the stack)
    [((((()()()){}){}){}){}]  #     minus the ASCII value of 0
    <(())>                    #     on top of a 1
  )                           #   close the push   
  {                           #   if not zero (ie. if not equal)
    ((<{}{}>))                #     replace the 1 from 3 lines back with a 0
  }{}                         #   end if and pop the extra 0
}                             # while the copied value != "0"
{}                            # pop the result of the equals check



2

R、33バイト

名前のない関数として実装

function(x)rle(x%%10^(0:99))$v[2]

これは、10 ^ 0から10 ^ 99のmodを適用します。 rle2番目の項目が常に必要な結果になるように、結果を減らすために使用されます。
オンラインでお試しください!


2

Zsh18 16バイト

<<<${(M)1%[^0]*}

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

Bash、25バイト

r=${1%[^0]*}
echo ${1#$r}

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


シェルは、正規表現を使用するために外部プログラムを呼び出す必要があるため、グロビングに対処する必要があります。

${1%[^0]*}拡張はゼロ以外の文字で始まる最短サフィックスと一致し、それを削除します。

  • Zshで、追加 (M)フラグをと、一致したサフィックスが削除される代わりに保持されます。
  • Bashでは、${1% }展開により、残っているものはすべてプレフィックスとして削除されます。

1

GNU sed17 14 + 1(rフラグ)= 15バイト

編集:ライリーのおかげで2バイト少ない

s:.*([^0]):\1:

これは、右端のゼロ以外の数字まですべてを削除することによって機能し、既存の後続ゼロとともに印刷されます。このスクリプトは、1回の実行で複数のテストを個別の行で処理できます。

オンラインでお試しください!(すべてのテスト例)


1

Mathematica、26バイト

数字のリストを取り、数字のリストを出力する純粋な関数:

#/.{___,x_,y:0...}:>{x,y}&

説明

#                           First argument
 /.                           Replace
   {                              start of list followed by
    ___,                          zero or more elements followed by
        x_,                       an element (referred to later as x) followed by
           y:0...                 a sequence of zero or more 0s (referred to later as y) followed by
                 }                end of list
                  :>            with
                    {x,y}         {x,y}
                         &   End of function.

これは、の左端の一致を検出するためxに機能します。これは、リストの右端のゼロ以外の要素である必要があります0


1

Java 8、47バイト

これは、に割り当て可能なラムダ式IntUnaryOperatorです。

x->{int m=1;for(;x%m<1;m*=10);return x%m*m/10;}

説明:mが10になるまでx%m0になり return x%m*m/10ます。mは目的の結果よりも1桁大きいため、除算が必要です。


1

Perl 6、10バイト

{+m/.0*$/}

簡単な正規表現ソリューション。数値を入力および出力します。


1

MATL10 7バイト

@Bのおかげで3バイト節約されました。メタ!

tfX>Jh)

入力と出力は数字の配列です。

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

または、すべてのテストケースを確認します

説明

t     % Input string implicitly. Duplicate
f     % Push indices of non-zero digits
X>    % Keep maximum, say k
Jh    % Attach 1j to give [k, 1j]. This is interpreted as an index "k:end"
)     % Index into original string. Display implcitly

入力と出力を整数のベクトルとして受け取ることができるため、48-3バイトを節約して完全に削除できます。オンラインで試してください!
B. Mehtaの

1

C#、30 28バイト

このJavaScriptの回答に基づいて、すべてのクレジットが彼に渡されると思います。

ゴルフ

i=a=>a%10<1?10*i(a/10):a%10;

1
i再帰を使用しているときに機能させるには、関数に明示的に名前を付ける必要があると思います。
エミグナ

@Emignaはあなたが正しいです!私はそれを見逃した:(
Metoniem

それを更新しましたが、それはこの方法が正しいかどう私がいない100%確信している
Metoniem

1
C#でこれに関するコンセンサスがわかりません。この構文は有効ですが、デリゲートが既に宣言されている場合にのみ機能します(そうiでない場合、再帰呼び出しでは宣言されません)。
エミグナ

1
aただし、括弧はどちらの方法でも必要ありません。
エミグナ

1

J、27バイト

10&|`(10*(p%&10))@.(0=10&|)

それはxnorの式に基づいているため、彼の功績です。


1

Kotlin、49バイト

ラムダ、に割り当て可能 (List<Int>) -> List<Int>

{a->a.slice(a.indexOfLast{it in 1..9}..a.size-1)}
  • 暗黙のパラメータ名itindexOfLast
  • .. 建物の範囲用

1

Perl 5、12バイト

11、プラス1の-nE代わりに-e

say/(.0*$)/

1

05AB1E、9バイト

RD0Ê1k>£R

オンラインでお試しください! またはテストスイートとして

説明

R          # reverse input
 D         # duplicate
  0Ê       # check each for inequality with 0
    1k     # get the index of the first 1
      >    # increment
       £   # take that many digits from the input
        R  # reverse



@MagicOctopusUrn:それは最後の数字をチェックするだけです。これは、最後のゼロ以外の数字であり、すべて後になります。
エミグナ



1

05AB1E、4 バイト

ĀÅ¡θ

数字のリストとしてのI / O。

オンラインそれを試してみたり、すべてのテストケースを検証(テストスイートが含まれている読みやすくするために参加)。

説明:

Ā     # Python-style truthify each digit in the (implicit) input-list (0 if 0; 1 if [1-9])
      #  i.e. [9,0,4,0,3,0,0] → [1,0,1,0,1,0,0]
 Å¡   # Split the (implicit) input-list on truthy values (1s)
      #  i.e. [9,0,4,0,3,0,0] and [1,0,1,0,1,0,0] → [[],[9,0],[4,0],[3,0,0]]
   θ  # And only leave the last inner list
      #  i.e. [[],[9,0],[4,0],[3,0,0]] → [3,0,0]
      # (after which it is output implicitly as result)


0

Haskell 57バイト

f(x:s)a|x=='0'=f s$'0':a|1>0=x:a
t x=f(reverse.show$x)[]

Input    -> Output
t 120    -> "20"
t 30200  -> "200"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.