Sayıyı en büyük basamağı ile azalt


33

Görev:

Ondalık sayı sistemindeki bir tam sayı verildiğinde, aşağıdaki gibi tek bir ondalık basamağa düşürün:

  1. Sayıyı ondalık basamak listesine dönüştürün.
  2. En büyük rakamı bul, D
  3. D'yi listeden çıkarın. Birden fazla D oluşumu varsa, soldan ilkini seçin (en önemli pozisyonda), diğerleri sağlam kalmalıdır.
  4. Sonuçtaki listeyi ondalık sayıya dönüştürün ve D ile çarpın.
  5. Sayı 9'dan büyükse (1 ondalık basamaktan büyükse), sonucu besleyerek tüm işlemi tekrarlayın. Tek basamaklı bir sonuç aldığınızda durun.
  6. Sonucu göster.

Örnek:

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.

14184 vb. İçin prosedürü tekrarlayarak devam ediyoruz ve aşağıdaki ara sonuçlardan geçiyoruz, sonunda 8'e ulaşıyoruz:

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

Yani 26364 için sonuç 8'dir.

Girdi: Bir tamsayı / bir tamsayıyı temsil eden bir dize

Çıktı: Sayıya uygulanan azaltmanın sonucu olan tek bir rakam.

Test durumları:

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

Bu , yani her dilde bayt cinsinden en kısa cevaplar kazanır.


3
Hangisi Rakam 10'dan büyükse veya 1 ondalık basamaktan fazlaysa . 10 sayısının 1 ondalık basamağı var, ancak ondan büyük değil.
Saat

@ Adám mantığı kodlayarak, sonra 10 -> 10?
Ian H.

1
@ Adám Haklısın, "9'dan büyük" yazmalıydım. Açıklamayı düzenleyeceğim. Teşekkürler!
Galen Ivanov

Birisi bu fonksiyonun histogramını yeterince büyük bölgeler için inceledi mi? Çok fazla sıfır var gibi görünüyor; Ayrıca, test senaryolarını oluştururken 8'li yıllarım oldu.
Galen Ivanov

2
Ayrıca, 4'e bölünebilen rastgele bir sayının, son iki hanenin ürününün 8 / 5'e bölünebilir olması 3/5 olasılığı vardır.
Ørjan Johansen

Yanıtlar:


18

05AB1E , 6 bayt

Kod:

[Dg#à*

05AB1E kodlamasını kullanır . Çevrimiçi deneyin!

açıklama

[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 bayt

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

Girdiyi, gibi bir tamsayı dizesi olarak alır f("26364").

Test Kılıfları



6

Pyth , 16 bayt

.WtH`*s.-ZKeSZsK

Dize olarak girdi alır. Burada dene! (Alternatif: .WtH`*s.-ZeSZseS)

Pyth , 18 bayt

.WgHT*s.-`ZKeS`ZsK

Bir tamsayı olarak girdi alır. Burada dene!

Nasıl çalışır

16-Byter

.WtH` * s.-ZKeSZsK ~ Tam program.

.W ~ Fonksiyonel iken. A (değer) truthy olsa da, değer = B (değer).
                 ~ Son değer döndürülür.
  tH ~ A, durum: [1:] değeri truthy mi? Uzunluk ≥ 2 mi?
    `* s.-ZKeSZsK ~ B, ayarlayıcı.
       .- ~ Bagwise çıkarma, en yüksek basamağı çıkarmak için ...
         Z ~ Geçerli değer Z ve ...
          KeSZ ~ En yüksek Z basamağı (String olarak). Ayrıca K değişkenine atar.
      s ~ Bir tamsayıya döküm.
     * ~ İle çarpılır ...
              sK ~ En yüksek basamak.
    `~ Bir Dizgeye Dönüştür.

18-Byter

.WgHT * s.-`ZKeS`ZsK ~ Tam program.

.W ~ Fonksiyonel iken. A (değer) truthy olsa da, değer = B (değer).
                   ~ Son değer döndürülür.
  gHT ~ A, durum: (H) ≥ 10 değeri
     * s.-`ZKES` ZSK ~ B, ayarlayıcı.
       Torbalı çıkarma (ilk oluşumun kaldırılmasında kullanılır).
         `Z ~ Z.
           KeS`Z ~ Ve Z'nin en yüksek (sözlüksel olarak) karakteri (en yüksek basamak).
                     Ayrıca onu K adı verilen bir değişkene atar.
      s ~ Tamsayıya dönüştür.
     * ~ Çarpın ...
                sK ~ K int a dökülür.

Jelly'e bu türden bir meydan okumada bu kadar yakın olmak Pyth IMO :-) için çok iyi


6

Kabuğu , 14 13 12 bayt

1 bayt tasarruf için teşekkürler Zgarb.

Ω≤9oṠS*od-▲d

Çevrimiçi deneyin!

Açıklama:

Ω≤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

Bazı yeniden düzenleme ile 12 bayt .
Zgarb

@Zgarb Teşekkürler, böyle bir şey arıyordum.
H.PWiz

6

R , 99 95 bayt

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)

Çevrimiçi deneyin!

Özyinelemeli bir işlev. f(number)Altbilgiye ekleme , diğer değerlerini test etmek için kullanılabilir number. Basit uygulama, dbasamakların listesidir ve 10^(n:2-2)%*%d[-M]sayıyı kaldırılan en büyük basamakla hesaplar.


5

Python 2,72 bayt

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

Çevrimiçi deneyin!


1
... Ben bir aptal hata ayıklama edildi bu . Kahretsin, ninja düştüm.
tamamen insan

Ben girdi 9 üzerinde bir hata alıyorum
RoryT

Bu test durumu için başarısız görünüyor 432969. "ValueError: int () temelli 10 (''" temelli int () için değişmez
James Webster

@JamesWebster şimdi düzeltilmelidir.
FlipTack

1
@recursive Hayır, o nzaman 0 olsaydı , o n*(n<=9)zaman hala sahte bir değer olarak değerlendirirdi, 0, özyinelemenin devam etmesini ve hataya neden olmasını sağlarken, dize '0'bir truthy değeridir ve özyineleme durur.
FlipTack


4

Jöle , 15 bayt

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

Çevrimiçi deneyin! veya test odasına bakın .

Nasıl?

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 bayt

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;}

Çevrimiçi deneyin!


PPCG'ye Hoşgeldiniz! Şunları yapabilirsiniz Bir boşluk kaldırmak .
Outgolfer Erik,

@EriktheOutgolfer Teşekkürler, bunu kaçırdım.
Timmeh

1
@totallyhuman Bazı refactoring işlemlerinden sonra 137'ye kadar teşekkür ederiz.
Timmeh

Değişebilirsin if(n<10)return n;...return F(...);ile tek dönüşüne üçlü-eğer böyle: 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 bayt )
Kevin Cruijssen

Bence using System.Linq;(18 bayt) bytecount içine eklemeniz gerekir.
Ian H.

4

APL (Dyalog) , 36 35 33 bayt

Güncellenen OP özellikleri nedeniyle -1. -2 sayesinde ngn.

Anonim zımni önek işlevi. Argüman olarak tamsayıyı alır.

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

Çevrimiçi deneyin!

{… Argümanın }olduğu bir fonksiyon :

⍵>9: eğer argüman 9'dan büyükse, o zaman:

  ⍕⍵ argümanı biçimlendir (dize)

  ⍎¨ her birini yürütünüz (değerlendirin) (bu rakamları sayı olarak alır)

  () Aşağıdaki zımni işlevi uygulayın

   ⌈/ en büyük rakam

   × zamanlar

   10⊥ base-10 kodunun çözülmesi (rakamları toplar)

    tüm basamaklar

   ⌷⍨¨ her biri tarafından dizine eklenmiş

   ⍳∘≢i basamak sayısı ndices

    -den farklı

   ⊢⍳⌈/Tüm rakamlar listesindeki  en büyük rakam olan i ndex

   bu konuda tekrar et (yani kendi kendine çağrı)

 Başka

   değiştirilmemiş argümanı döndür


Gerekmiyor >10olmak >9?
Outgolfer Erik

@EriktheOutgolfer Muhtemelen, ancak OP aslında bu konuda net değil (kendinden çelişkili).
21’de

Bu doğru, ancak >9bir bayt kurtarır.
Outgolfer Erik,

@EriktheOutgolfer Güncelleştirildi.
17:17

@ Adám ∇ yerine by = -1 bayt: {⍵> 9: ∇ (⌈ / ... ⋄⍵}
1717

3

Perl 6 ,  45  41 bayt

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

Dene

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

Dene

Expanded:

{  # 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 bayt

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

Çevrimiçi deneyin! Link, Dennis'in sunucusunu kırmayacak kadar hızlı test senaryolarını içeriyor. Açıklama:

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

İki basamaklı sayılar için, bu sayıyı ;ayırıcı ile çoğaltır ve çoğaltmaya 1 ekler. Bir basamaklı sayılar için bu 1;, sayıya önek ekler .

O`\G\d

Çoğaltmanın basamaklarını sıralayın. (Bir basamaklı sayılar için bunun bir etkisi yoktur.)

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

En büyük basamağın ilk oluşumunu bulun ve silin, ayrıca kopyadaki diğer basamağı ve daha önce eklenmiş ekstra 1'i silin. (Bir basamaklı sayılar için, eşleşme başarısız olur, böylece hiçbir şey yapmaz.)

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

Sayıyı rakam ile çarpın. Bir basamaklı sayılar için bu, orijinal sayıyla sonuçlanır ve döngü sona erer. Aksi halde, program tek bir rakama ulaşılana kadar döngüler.


3

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

@Raznagul sayesinde 13 bayt kaydedildi!

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);}

Çevrimiçi deneyin!


Değişebilirsin s.Length<2için n<10. Ayrıca, üçlü operatörü kaldırabilir ve return f(y)durumun sonunda, durumun ifözyinelemenin bir sonraki adımında ele alındığı gibi kaldırabilirsiniz .
raznagul

3

Java 8, 126 104 bayt

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

@ OlivierGrégoire sayesinde -22 bayt .

Açıklama:

Burada dene.

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 bayt (yukarıdakiyle aynı, ancak özyinelemeli yerine yinelemeli, ayrıca: n>9yerine geri döndürülmeli n<10).
Olivier Grégoire

2

Jq 1.5 , 86 bayt

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

Expanded

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
)

Çevrimiçi deneyin!



2

Lua, 137 108 bayt

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

Jonathan S'a 29 byte golf attığı için teşekkür ederiz.

Çevrimiçi deneyin!



Teşekkürler. Bu, kendi cevabına layık görünüyor - bunun için yaptığınız bir gönderiye bağlantı verecek, aksi halde düzenleyecek ve kredi verecektir.
MCAdventure10

Sadece düzenleyin. Hala sizin kodunuz, sıfırdan yazmadım.
Jonathan S.

2

D , 188 186 185 bayt

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);}

Çevrimiçi deneyin!

Tembel değerlendirmeden çok nefret ediyorum. Herhangi bir ipucu bekliyoruz!


2

Lua, 154 Bayt

Bunu golf oynamak için bazı yollarım olmalı, şu an deniyorum.

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)

Çevrimiçi deneyin!

açıklamalar

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 bayt

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

Çevrimiçi deneyin!

Ooof. PowerShell dizileri değişkendir, bu [Collections.ArrayList]yüzden .remove()daha sonra arayabilmek için burada uzun döküm kullanmamız gerekir .

Girdiyi alır $args, dizgeye dönüştürür, sonra bir char-array, sonra bir ArrayList. Bu içine saklar $a. O zaman whileya da altına gidene kadar döngü yapıyoruz 9. Her yinelemede, .removeen büyük öğeyi $a( en büyük öğeyi içine sortalarak ve alarak [-1]) en büyük öğeyi çağırıyoruz .$b aynı anda. Bu işe yarar, çünkü ASCII değerleri değişmez rakamlarla aynı şekilde sıralanır.

Daha sonra $a, yine bir- chardizisi olarak (ve ArrayListdolaylı olarak), $b(şu anda a char) olan bir dizgeye, sonra bir int ile +ve sonra onu bir dizgeye çarparak ( dolaylı olarak int'ye yazılır ) çarparak yeniden hesaplıyoruz $a -join. Bu, mücadelenin "D ile çarpma" bölümünü karşılar.

Son olarak, bir kez döngü dışına çıktığımızda $a, boru hattına koyarız ve çıktı kapalıdır.


2

Pip , 22 21 bayt

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

Komut satırı argümanı olarak girdi alır. Tüm test durumlarını doğrulayın: Çevrimiçi deneyin!

açıklama

Ungolfed, yorumlarla:

                 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

Golf versiyonunda, halka gövdesi tek bir ifadede yoğunlaştırılır:

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 bayt


Jo King sayesinde -10 bayt

Maalesef tekrar tekrar bir lambda işlevini çağıramazsınız, bu nedenle yöntem başlığı için fazladan 11 bayt gerekir. Bunun yerine döngüler için kısa bir Java cevabı olduğunu biliyorum, ancak bunu kendi başıma bulmaya karar verdim.

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

Çevrimiçi deneyin


-48Haritadan mtanımın sonuna gidebilirsiniz . Çevrimiçi deneyin! Ayrıca TIO bağlantınızda fazladan bir boşluk var
Jo King

@JoKing teşekkürler.
Benjamin Urquhart

1

J, 40 bayt

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

Çevrimiçi deneyin!

açıklama

(      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
Üçlü kutu seçimini bugün sizden öğrendim, teşekkür ederim!
Galen Ivanov

1

Güç kalkanı , 230 bayt

$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

Çevrimiçi deneyin!

Tüm tip dökümlerde çok fazla harcanmıştır.


1

PHP, 82 77 + 1 bayt

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

Pipe ile çalıştırın -nRveya çevrimiçi deneyin .


1

dc , 98 85 bayt

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

Kullanma fikri için bu cevaba çok teşekkürler~ rakamlardan çıkarılmasında , kodun orjinal versiyonunda iki bayt ile sonuçlandı.

Bu, tamamlanmak için bir olsa da dc varolmayan dize manipülasyon kabiliyetleriyle gerçekti.

Çevrimiçi deneyin!


1

Bash, 80 bayt

Paketleri Core Utilities kullanır ( sortve için tail) ve grep.

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

O nasıl çalışır?

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`
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.