Kurangi angka dengan digit terbesarnya


33

Tugas:

Diberi angka integer dalam sistem angka desimal, kurangi menjadi satu angka desimal tunggal sebagai berikut:

  1. Ubah nomor menjadi daftar angka desimal.
  2. Temukan digit terbesar, D
  3. Hapus D dari daftar. Jika ada lebih dari satu kejadian D, pilih yang pertama dari kiri (pada posisi paling signifikan), semua yang lain harus tetap utuh.
  4. Konversikan daftar yang dihasilkan menjadi angka desimal dan kalikan dengan D.
  5. Jika jumlahnya lebih besar dari 9 (memiliki lebih dari 1 digit desimal), ulangi seluruh prosedur, dan masukkan hasilnya ke dalamnya. Berhentilah ketika Anda mendapatkan hasil satu digit.
  6. Tampilkan hasilnya.

Contoh:

26364 -> 
1. 2 6 3 6 4 
2. The largest digit is 6, so D=6
3. There are two occurrences or 6: at positions 1 and 3 (0-based). We remove the left one,
    at position 1 and get the list 2 3 6 4 
4. we convert the list 2 3 6 4 to 2364 and multiply it by D:
   2364 * 6 = 14184
5. 14184 is greater than 9 so we repeat the procedure, feeding 14184 into it.

Kami melanjutkan dengan mengulangi prosedur untuk 14184 dan seterusnya dan kami melewati hasil antara berikut, akhirnya mencapai 8:

11312
3336
1998
1782
1376
952
468
368
288
224
88
64
24
8

Jadi hasil untuk 26364 adalah 8.

Input: Integer / string yang mewakili integer

Output: Satu digit, hasil reduksi diterapkan ke nomor tersebut.

Kasus uji:

9 -> 9
27 -> 4
757 -> 5
1234 -> 8
26364 -> 8
432969 -> 0
1234584 -> 8
91273716 -> 6

Ini adalah , jadi jawaban tersingkat dalam byte di setiap bahasa menang.


3
Yang mana Jika angkanya lebih besar dari 10 atau memiliki lebih dari 1 angka desimal . Angka 10 memiliki lebih dari 1 digit desimal, tetapi tidak lebih besar dari sepuluh.
Adám

@ Adám Dengan mengkode logika, haruskah demikian 10 -> 10?
Ian H.

1
@ Adám Anda benar, saya seharusnya menulis "lebih besar dari 9". Saya akan mengedit deskripsi. Terima kasih!
Galen Ivanov

Adakah yang memeriksa histogram fungsi ini untuk wilayah yang cukup luas? Tampaknya memiliki banyak nol; Saya juga mendapat 8s banyak saat menyusun test case.
Galen Ivanov

2
Juga, angka acak yang dapat dibagi dengan 4 memiliki probabilitas 3/5 dari produk dari dua digit terakhir yang dapat dibagi oleh 8.
Ørjan Johansen

Jawaban:


18

05AB1E , 6 byte

Kode:

[Dg#à*

Menggunakan penyandian 05AB1E . Cobalah online!

Penjelasan

[Dg#     # While the length of the number is not 1
    à    # Extract the largest element from the current number
     *   # Multiply it with the leftover number

11

JavaScript (ES6), 49 byte

f=n=>n>9?f(""+n.replace(m=Math.max(...n),"")*m):n

Mengambil input sebagai representasi string dari integer, seperti f("26364").

Uji Kasus



6

Pyth , 16 byte

.WtH`*s.-ZKeSZsK

Mengambil input sebagai sebuah String. Coba di sini! (Alternatif: .WtH`*s.-ZeSZseS)

Pyth , 18 byte

.WgHT*s.-`ZKeS`ZsK

Mengambil input sebagai integer. Coba di sini!

Bagaimana itu bekerja

16-byter

.WtH` * s.-ZKeSZsK ~ Program lengkap.

.W ~ Sementara fungsional. Sementara A (nilai) benar, nilai = B (nilai).
                 ~ Nilai akhir dikembalikan.
  tH ~ A, kondisi: Apakah nilai [1:] benar? Apakah panjangnya ≥ 2?
    `* s.-ZKeSZsK ~ B, setter.
       .- ~ Pengurangan Bagwise, digunakan untuk menghapus digit tertinggi, dengan ...
         Z ~ Nilai saat ini Z, dan ...
          KeSZ ~ Digit tertinggi Z (sebagai String). Juga menetapkan variabel K.
      s ~ Dicor ke integer.
     * ~ Dikalikan dengan ...
              sK ~ Digit tertinggi.
    `~ Konversi ke String.

18-byter

.WgHT * s.-`ZKeS`ZsK ~ Program lengkap.

.W ~ Sementara fungsional. Sementara A (nilai) benar, nilai = B (nilai).
                   ~ Nilai akhir dikembalikan.
  gHT ~ A, kondisi: adalah nilai (H) ≥ 10?
     * s.-`ZKeS`ZsK ~ B, setter.
       .- ~ Substraksi bagwise (digunakan untuk menghilangkan kejadian pertama).
         `Z ~ Representasi string dari Z.
           KeS`Z ~ Dan karakter tertinggi (leksikografis) dari Z (digit tertinggi).
                     Itu juga menugaskannya ke variabel yang disebut K.
      s ~ Cast ke integer.
     * ~ Kalikan dengan ...
                sK ~ K dicor ke int.

Menjadi yang dekat dengan Jelly pada jenis tantangan seperti itu sangat baik untuk Pyth IMO :-)


6

Sekam , 14 13 12 byte

Terima kasih Zgarb untuk menghemat 1 byte.

Ω≤9oṠS*od-▲d

Cobalah online!

Penjelasan:

Ω≤9            Repeat the following function until the result is ≤ 9
           d     Convert to a list of digits
         -▲      Remove the largest one
       od        Convert back to an integer
   oṠS*          Multiply by the maximum digit

12 byte dengan pengaturan ulang.
Zgarb

@ Zgarb Terima kasih, saya mencari sesuatu seperti itu.
H.PWiz

6

R , 99 95 byte

f=function(x)"if"(n<-nchar(x)-1,f(10^(n:1-1)%*%(d=x%/%10^(n:0)%%10)[-(M=which.max(d))]*d[M]),x)

Cobalah online!

Fungsi rekursif. Menambahkan f(number)footer dapat digunakan untuk menguji nilai-nilai lain dari number. Implementasi langsung, dadalah daftar digit, dan 10^(n:2-2)%*%d[-M]menghitung angka dengan digit terbesar dihapus.


5

Python 2 , 72 byte

f=lambda n:`n`*(n<=9)or f(int(`n`.replace(max(`n`),'',1))*int(max(`n`)))

Cobalah online!


1
... Saya sedang men-debug kesalahan bodoh dalam hal ini . Sial, aku ninja.
manusiawi

Saya mendapat pesan kesalahan pada input 9
RoryT

Ini tampaknya gagal untuk test case 432969. "ValueError: literal for int () tidak valid dengan basis 10: ''"
James Webster

@ JamesWebster harus diperbaiki sekarang.
FlipTack

1
@recursive Tidak, ketika itu jika n0 maka n*(n<=9)akan tetap mengevaluasi ke nilai falsy, 0, membuat rekursi berlanjut dan menyebabkan kesalahan, sedangkan string '0'adalah nilai yang benar dan karena itu rekursi dihentikan.
FlipTack


4

Jelly , 15 byte

D×Ṁ$œṡṀ$FḌµ>9µ¿

Cobalah online! atau lihat test-suite .

Bagaimana?

D×Ṁ$œṡṀ$FḌµ>9µ¿ - Link: number, n
              ¿ - while:
             µ  - ...condition (monadic):
            9   -    literal 9
           >    -    loop value greater than (9)?
          µ     - ...do (monadic):               e.g. 432969
D               -    convert to a decimal list        [4,3,2,9,6,9]
   $            -    last two links as a monad:
  Ṁ             -      maximum                         9
 ×              -      multiply (vectorises)          [36,27,18,81,54,81]
       $        -    last two links as a monad:
      Ṁ         -      maximum                         81
    œṡ          -      split at first occurrence      [[36,27,18],[54,81]]
        F       -    flatten                          [36,27,18,54,81]
         Ḍ      -    convert from base 10              389421  (i.e. 360000 + 27000 + 1800 + 540 + 81)


4

C # (.NET Core) , 126 byte

int F(int n){var x=(n+"").ToList();var m=x.Max();x.RemoveAt(x.IndexOf(m));return n>9?F(int.Parse(string.Concat(x))*(m-48)):n;}

Cobalah online!


Selamat datang di PPCG! Anda dapat menghapus spasi .
Erik the Outgolfer

@EriktheOutgolfer Terima kasih, melewatkan yang itu.
Timmeh

1
@totallyhuman Terima kasih, turun ke 137 setelah beberapa refactoring.
Timmeh

Anda dapat mengubah if(n<10)return n;...return F(...);ke pengembalian tunggal dengan ternary-if, seperti ini: int F(int n){var x=(n+"").ToList();var m=x.Max(d=>d);x.RemoveAt(x.IndexOf(m));return n<10?n:F(int.Parse(string.Concat(x))*(m-48));}( 131 bytes )
Kevin Cruijssen

Saya pikir Anda perlu memasukkan using System.Linq;(18 byte) ke dalam bytecount.
Ian H.

4

APL (Dyalog) , 36 35 33 byte

-1 karena spesifikasi OP yang diperbarui. -2 Terima kasih kepada ngn.

Fungsi awalan diam-diam anonim. Mengambil integer sebagai argumen.

{⍵>9:∇(⌈/×10⊥⊂⌷⍨¨⍳∘≢~⊢⍳⌈/)⍎¨⍕⍵⋄⍵}

Cobalah online!

{... }fungsi di mana argumennya:

⍵>9: jika argumen lebih besar dari 9, maka:

  ⍕⍵ format (stringify) argumen

  ⍎¨ mengeksekusi (mengevaluasi) masing-masing (ini memberi kita digit sebagai angka)

  (...)  terapkan fungsi diam-diam berikut pada mereka

   ⌈/ digit terbesar

   × waktu

   10⊥ decoding basis-10 dari (mengumpulkan angka)

    semua digit

   ⌷⍨¨ diindeks oleh masing-masing

   ⍳∘≢ yang saya ndices dari jumlah digit

    berbeda dari

   ⊢⍳⌈/ digit terbesar adalah i ndex di seluruh daftar digit

   berulang (yaitu menyebut diri) itu

 lain

   kembalikan argumen yang tidak dimodifikasi


Tidak >10seharusnya >9?
Erik the Outgolfer

@EriktheOutgolfer Mungkin, tapi OP sebenarnya tidak jelas (kontradiktif sendiri) tentang itu.
Adám

Itu benar, tetapi >9akan menghemat satu byte.
Erik the Outgolfer

@EriktheOutgolfer Diperbarui.
Adám

@ Adám ∇ alih-alih ⍣ = untuk -1 byte: {⍵> 9: ∇ (⌈ / ... ⋄⍵}
ngn

3

Perl 6 ,  45  41 byte

{($_,{$/=.comb.max;S/"$/"//*$/}...10>*).tail}

Menguji

{($_,{S/"{.comb.max}"//*$/}...10>*).tail}

Menguji

Diperluas:

{  # bare block lambda with implicit parameter 「$_」

  (  # generate the sequence

      $_,                      # start the sequence with the input

      {                        # generate the rest of the values in the sequence

          S/                   # find and replace (not in-place)
            "{  .comb.max  }"  # find the max digit and match against it
          //                   # replace it with nothing
          *                    # multiply the result with
          $/                   # the digit that was removed
      }

      ...                      # keep generating values until

      10 > *                   # the value is less than 10

  ).tail                       # get the last value from the sequence
}

3

Retina , 67 byte

{1`(..+)?
1$&;$&
O`\G\d
.+((.);.*?)\2
$1
\d+
$*
1(?=.*;(1+))|.
$1
1

Cobalah online! Tautan mencakup uji kasus yang cukup cepat untuk tidak memukul server Dennis. Penjelasan:

{1`(..+)?
1$&;$&

Untuk dua angka digit, ini menggandakan angka dengan ;pemisah, awalan 1 ke duplikat. Untuk satu angka digit, ini awalan 1;ke angka.

O`\G\d

Sortir digit dari duplikat. (Untuk satu angka digit, ini tidak berpengaruh.)

.+((.);.*?)\2
$1

Temukan kemunculan pertama digit terbesar, dan hapus angka itu, dan juga digit lainnya dalam duplikat, dan angka 1 tambahan yang ditambahkan sebelumnya. (Untuk satu angka angka, pertandingan gagal jadi ini tidak berarti apa-apa.)

\d+
$*
1(?=.*;(1+))|.
$1
1

Lipat gandakan angka dengan digit. Untuk satu angka angka, ini menghasilkan angka asli, dan loop berakhir. Jika tidak, program akan berputar hingga satu digit tercapai.


3

C # (.NET Core) , 177 164 + 18 byte

Disimpan 13 byte berkat @raznagul!

int f(int n){string s=n+"",m=s.Max(d=>d)+"";if(n<10)return n;var x=s.ToList();x.RemoveAt(s.IndexOf(m));int y=int.Parse(string.Join("",x))*int.Parse(m);return f(y);}

Cobalah online!


Anda bisa berubah s.Length<2menjadi n<10. Selain itu, Anda dapat menghapus operator ternary dan tepat return f(y)pada akhirnya, karena kasing ditangani oleh ifpada langkah rekursi berikutnya.
raznagul

3

Java 8, 126 104 byte

n->{for(;n>9;n=new Long((n+"").replaceFirst((n=(n+"").chars().max().getAsInt()-48)+"",""))*n);return n;}

-22 byte terima kasih kepada @ OlivierGrégoire .

Penjelasan:

Coba di sini.

n->{         // Method with long as both parameter and return-type
  for(;n>9;  //  Loop as long as the number contains more than 1 digit
    n=       //   Replace the current number with:
      new Long((n+"").replaceFirst((n=(n+"").chars().max().getAsInt()-48)+"",""))
             //    Remove the first largest digit from the number,
      *n     //    and multiply this new number with the removed digit
  );         //  End of loop
  return n;  //  Return the result
}            // End of method


1
104 byte (sama seperti di atas, tetapi berulang bukan rekursif, juga: n>9dan mengembalikan kondisi alih-alih n<10).
Olivier Grégoire

2

Jq 1,5 , 86 byte

until(.<10;"\(.)"|(./""|max)as$v|index($v)as$x|.[:$x]+.[1+$x:]|tonumber*($v|tonumber))

Diperluas

until(
    .<10                    # until number is below 10
  ; "\(.)"                  # convert to string
  | (./""|max) as $v        # find largest digit, call it $v
  | index($v) as $x         # find index of digit
  | .[:$x]+.[1+$x:]         # remove digit
  | tonumber*($v|tonumber)  # convert back to number and multiply by $v
)

Cobalah online!



2

Lua, 137 108 byte

function f(n)while n>9 do b="0"g=b.gsub g(n,".",function(m)b=math.max(m,b)end)n=b*g(n,b,"",1)end print(n)end

Terima kasih kepada Jonathan S untuk bermain golf 29 byte.

Cobalah online!



Terima kasih. Itu kelihatannya layak jawaban sendiri - akan menghubungkan ke posting yang Anda buat untuk itu, jika tidak akan mengedit & kredit.
MCAdventure10

Edit saja. Ini masih kode Anda, saya belum menulisnya dari awal.
Jonathan S.

2

D , 188 186 185 byte

import std.conv,std.algorithm;T f(T,U=string)(T u){if(u<10)return u;T[]r;u.text.each!(n=>r~=n.to!T-48);T m=r.maxElement;U s;r.remove(r.maxIndex).each!(n=>s~=n.to!U);return f(m*s.to!T);}

Cobalah online!

Aku benci evaluasi malas, sangat banyak. Ada tips yang diterima!


2

Lua, 154 Bytes

Saya harus memiliki beberapa cara untuk menurunkan ini, saya sedang bereksperimen sekarang.

n=...z=table
while n+0>9 do
t={}T={}n=n..''n:gsub(".",function(c)t[#t+1]=c T[#T+1]=c
end)z.sort(t)x=t[#t]z.remove(T,n:find(x))n=z.concat(T)*x
end
print(n)

Cobalah online!

Penjelasan

n=...                    -- define n as a shorthand for the argument
z=table                  -- define z as a pointer to the object table
while n+0>9              -- iterate as long as n is greater than 9
do                       -- n+0 ensure that we're using a number to do the comparison
  t={}                   -- intialise two tables, one is used to find the greatest digit
  T={}                   -- the other one is used to remove it from the string
  n=n..''                -- ensure that n is a string (mandatory after the first loop)
  n:gsub(".",function(c) -- apply an anonymous function to each character in n
               t[#t+1]=c -- fill our tables with the digits
               T[#T+1]=c
             end)        
  z.sort(t)              -- sort t to put the greatest digit in the last index
  x=t[#t]                -- intialise x to the value of the greatest digit
  z.remove(T,n:find(x))  -- remove the first occurence of x from the table T 
                         -- based on its position in the input string
  n=z.concat(T)*x        -- assign the new value to n
end                      -- if it still isn't a single digit, we're looping over again
print(n)                 -- output the answer

2

PowerShell , 123 byte

[Collections.ArrayList]$a=[char[]]"$args"
while(9-lt-join$a){$a.remove(($b=($a|sort)[-1]));$a=[char[]]"$(+"$b"*-join$a)"}$a

Cobalah online!

Ooof. Array PowerShell tidak dapat diubah, jadi kita perlu menggunakan [Collections.ArrayList]casting yang panjang di sini agar kita dapat memanggil.remove() nanti.

Mengambil input $args, mengubahnya menjadi string, lalu char-array, lalu sebuah ArrayList. Simpan itu ke dalam $a. Lalu kita whileputar sampai kita berada di atau di bawah 9. Setiap iterasi, kami memanggil .removeelemen terbesar $a(dilakukan oleh sortdan mengambil elemen terakhir [-1]), menyimpan elemen terbesar ke dalam $bpada saat yang sama. Ini terjadi karena nilai-nilai ASCII mengurutkan dengan cara yang sama dengan digit literal.

Selanjutnya, kita menghitung ulang $a, lagi sebagai char-array (dan ArrayListsecara implisit), dengan melemparkan $b(yang saat ini char) ke string, kemudian int dengan +, dan mengalikannya ke$a -join diedit ke dalam string (secara implisit dilemparkan ke int). Ini memenuhi bagian tantangan "gandakan dengan D".

Akhirnya, begitu kita keluar dari loop, kita meletakkan $ake dalam pipa dan output tersirat.


2

Pip , 22 21 byte

Wa>9a:aRAa@?YMXax*:ya

Mengambil input sebagai argumen baris perintah. Verifikasi semua kasus uji: Coba online!

Penjelasan

Tidak disatukan, dengan komentar:

                 a is 1st cmdline arg
W a>9 {          While a > 9:
  Y MXa           Yank max(a) into y
  a RA: a@?y ""   Find index of y in a; replace the character at that position with ""
  a *: y          Multiply a by y
}
a                Autoprint a

Dalam versi golf, badan loop dikondensasi menjadi satu ekspresi:

a:aRAa@?YMXax*:y
        YMXa      Yank max(a)
     a@?          Find its index in a
  aRA       x     Replace at that index with x (preinitialized to "")
             *:y  Multiply that result by y (using : meta-operator to lower the precedence)
a:                Assign back to a


2

Java 8: 115 byte


-10 byte terima kasih kepada Jo King

Sayangnya Anda tidak dapat memanggil fungsi lambda secara rekursif, sehingga diperlukan 11 byte tambahan untuk header metode. Saya sadar ada jawaban Java yang lebih pendek yang sebagai gantinya, tetapi saya memutuskan untuk membuat ini sendiri.

long f(long n){int m=(n+"").chars().max().getAsInt()-48;return n>9?f(new Long((n+"").replaceFirst(""+m,""))*m):n;};

Cobalah online


Anda dapat memindahkan -48dari peta ke akhir mdefinisi. Cobalah online! Anda juga memiliki ruang kosong ekstra di tautan TIO Anda
Jo King

@JoKing, terima kasih.
Benjamin Urquhart

1

J, 40 byte

((]*<^:3@i.{[)>./)&.(10&#.inv)^:(9&<)^:_

Cobalah online!

penjelasan

(      iterate                   )^:(9&<)^:_    NB. keep iterating while the number is > 9
 (     stuff         )&.(10&#.inv)              NB. convert to digits, do stuff, convert back to number
 (           )>./)                              NB. stuff is a hook, with max digit >./  on the right
 (]*<^:3@i.{[)                                  NB. so that in this phrase, ] means "max" and [ means "all digits"
  ]                                             NB. the max digit...
   *                                            NB. times...        
    <^:3@                                       NB. triple box...
         i.                                     NB. the first index of the max in the list of all digits
           {                                    NB. "from" -- which because of the triple box means "take all indexes except..."
            [                                   NB. from all the digits of the number

1
Saya belajar tentang pemilihan kotak tiga dari Anda hari ini, terima kasih!
Galen Ivanov

1

PowerShell , 230 byte

$n="$args";do{$n=$n.ToString();$a=@();0..$n.Length|%{$a+=$n[$_]};$g=[convert]::ToInt32(($a|sort|select -last 1),10);[regex]$p=$g.ToString();[int]$s=$p.replace($n,'',1);if($n.Length-eq1){$n;exit}else{$r=$s*$g}$n=$r}until($r-lt10)$r

Cobalah online!

Membuang terlalu banyak pada semua jenis casting.


1

PHP, 82 77 +1 byte

for($n=$argn;$n>9;)$n=join("",explode($d=max(str_split($n)),$n,2))*$d;echo$n;

Jalankan sebagai pipa dengan -nRatau coba online .


1

dc , 98 85 byte

?dsj[0dsosclj[soIlc^sr0]sn[I~dlo!>nrlc1+scd0<i]dsixljdlr%rlrI*/lr*+lo*dsj9<T]sT9<Tljp

Banyak terima kasih atas jawaban ini untuk ide memanfaatkan ~ekstraksi angka dari angka, menghasilkan dua byte yang disimpan atas versi asli kode.

Ini adalah sesuatu yang agak lengkap dcdengan kemampuan memanipulasi string yang tidak ada.

Cobalah online!


1

Bash, 80 byte

Menggunakan paket - paket Utilitas Inti (untuk sortdan tail) dan grep.

while((n>9));do m=$(grep -o .<<<$n|sort|tail -n1);n=$((${n/$m/}*m));done;echo $n

Bagaimana cara kerjanya?

while (( n > 9 )); do  # C-style loop conditional
    grep -o .          # Separate the string into one char per line
              <<< $n   # Use the content of variable `n` as its stdin
    | sort             # Pipe to `sort`, which sorts strings by line
    | tail -n 1        # Take the last line

m=$(                 ) # Assign the output of the command chain to `m`
n=$((          ))      # Assign the result of the evaluation to n
     ${n/$m/}          # Replace the first occurrence of $m with empty
             *m        # ... and multiply it by the value of `m`
done; echo $n          # After loop, print the value of `n`
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.