최대 자릿수로 숫자 줄이기


33

태스크:

10 진수 시스템에 정수가 주어지면 다음과 같이 단일 10 진수로 줄이십시오.

  1. 숫자를 10 진수 목록으로 변환하십시오.
  2. 가장 큰 숫자, D 찾기
  3. 목록에서 D를 제거하십시오. D가 두 번 이상 발생하는 경우 왼쪽에서 가장 중요한 위치에서 첫 번째 항목을 선택하면 다른 모든 항목은 그대로 유지됩니다.
  4. 결과 목록을 10 진수로 변환하고 D를 곱하십시오.
  5. 숫자가 9보다 크면 (10 진수가 1보다 큼) 전체 절차를 반복하여 결과를 입력하십시오. 한 자리 결과가 나오면 중지하십시오.
  6. 결과를 표시하십시오.

예:

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에 대한 절차를 계속 반복하여 다음과 같은 중간 결과를 거쳐 마침내 8에 도달합니다.

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

따라서 26364의 결과는 8입니다.

입력 : 정수 / 정수를 나타내는 문자열

출력 : 숫자에 적용된 축소의 결과 인 한 자릿수.

테스트 사례 :

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

이것은 이므로 각 언어에서 가장 짧은 바이트 단위의 답변이 이깁니다.


3
어느 그 것이다 수가보다 더 큰 10 인 경우 또는 1 개 이상의 소수 자리가 있습니다 . 숫자 10의 십진수는 1보다 크지 만 10보다 크지 않습니다.
Adám

@ Adám 논리를 코딩함으로써, 그렇다면 10 -> 10?
Ian H.

1
@ Adám 당신은 옳습니다, 나는 "9보다 큰"을 작성해야합니다. 설명을 편집하겠습니다. 감사!
Galen Ivanov

누군가가 충분히 큰 지역에 대해이 기능의 히스토그램을 조사 했습니까? 0이 많은 것 같습니다. 또한 테스트 사례를 작성하는 동안 많은 8을 얻었습니다.
Galen Ivanov

2
또한, (4)에 의한 난수에 의해 나누어 8. 마지막 두 자리 인 나눌의 생성물 3/5 확률을 갖는다
Ørjan 요한센

답변:



11

자바 스크립트 (ES6), 49 바이트

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

입력을처럼 정수의 문자열 표현으로 사용합니다 f("26364").

테스트 사례



6

Pyth , 16 바이트

.WtH`*s.-ZKeSZsK

입력을 문자열로받습니다. 여기 사용해보십시오! (대체 : .WtH`*s.-ZeSZseS)

Pyth , 18 바이트

.WgHT*s.-`ZKeS`ZsK

입력을 정수로 취합니다. 여기 사용해보십시오!

작동 원리

16 바이트

.WtH` * s.-ZKeSZsK ~ 전체 프로그램.

.W ~ 기능적. A (값)는 사실이지만 값 = B (값)입니다.
                 ~ 최종 값이 반환됩니다.
  tH ~ A, 조건 : value [1 :]이 진실입니까? 길이가 2 이상입니까?
    `* s.-ZKeSZsK ~ B, 세터.
       .- ~ Bagwise 빼기, 가장 높은 자리를 제거하는 데 사용되며 ...
         Z ~ 현재 값 Z 및 ...
          KeSZ ~ Z의 가장 높은 자리수 (문자열). 변수 K에도 할당합니다.
      s ~ 정수로 캐스트되었습니다.
     * ~ 곱하기 ...
              sK ~ 가장 높은 자리.
    `~ 문자열로 변환합니다.

18 바이트

.WgHT * s.-`ZKeS`ZsK ~ 전체 프로그램.

.W ~ 기능적. A (값)는 사실이지만 값 = B (값)입니다.
                   ~ 최종 값이 반환됩니다.
  gHT ~ A, 조건 : 값 (H)이 10 이상입니까?
     * s.-`ZKeS`ZsK ~ B, 세터.
       .- ~ Bagwise 빼기 (첫 번째 항목을 제거하는 데 사용).
         `Z ~ Z의 문자열 표현.
           KeS`Z ~ 그리고 Z (가장 높은 숫자)의 가장 높은 문자 (문자)입니다.
                     또한 K라는 변수에 할당합니다.
      s ~ 정수로 캐스트
     * ~ 곱하기 ...
                sK ~ K는 int로 캐스팅되었습니다.

이어서 그 주변 IMO Pyth을 위해 아주 좋은 도전의 같은 종류의 젤리로되어 :-)


6

껍질 , 14 13 12 바이트

1 바이트를 절약 해 준 Zgarb에게 감사드립니다.

Ω≤9oṠS*od-▲d

온라인으로 사용해보십시오!

설명:

Ω≤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 바이트 .
Zgarb

@ Zgarb 감사합니다, 나는 그런 것을 찾고있었습니다.
H.PWiz

6

R , 99 95 바이트

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)

온라인으로 사용해보십시오!

재귀 함수 f(number)바닥 글에 추가하면의 다른 값을 테스트하는 데 사용할 수 있습니다 number. 간단한 구현 d은 자릿수 목록이며 10^(n:2-2)%*%d[-M]가장 큰 자릿수가 제거 된 숫자를 계산합니다.


5

파이썬 2 , 72 바이트

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

온라인으로 사용해보십시오!


1
... 멍청한 실수를 디버깅하고있었습니다 . 젠장, 닌자가 있어요
완전히 인간적인

I 입력 9 오류를 받고 있어요
RoryT

이것은 테스트 케이스에 실패한 것 같습니다 432969. "에 ValueError : 기본 10 INT ()에 대한 유효하지 않은 문자 : ''"
제임스 웹스터

@JamesWebster가 수정되었습니다.
FlipTack

1
@recursive No n는 0 인 것처럼 n*(n<=9)여전히 잘못된 값인 0으로 평가되어 재귀를 계속하고 오류를 발생시키는 반면 문자열 '0'은 정확한 값이므로 재귀는 중지됩니다.
FlipTack


4

젤리 , 15 바이트

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

온라인으로 사용해보십시오! 또는 테스트 스위트를 참조하십시오.

방법?

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 코어) 126 바이트

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

온라인으로 사용해보십시오!


PPCG에 오신 것을 환영합니다! 공백을 제거 할 수 있습니다 .
Outgolfer Erik

@EriktheOutgolfer 감사합니다.
Timmeh

1
@totallyhuman 리팩토링 후 137까지 감사합니다.
Timmeh

다음 if(n<10)return n;...return F(...);과 같이 3 진 경우 단일 반환으로 변경할 수 있습니다 . 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

using System.Linq;바이트 수에 (18 바이트) 를 포함시켜야한다고 생각합니다 .
Ian H.

4

APL (Dyalog) , 36 35 33 바이트

업데이트 된 OP 사양으로 인해 -1입니다. ngn 덕분에 -2입니다.

익명의 암묵적 접두사 기능. 정수를 인수로 사용합니다.

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

온라인으로 사용해보십시오!

{... }함수 곳 인수는 다음과 같습니다

⍵>9: 인수가 9보다 큰 경우 :

  ⍕⍵ 인수를 형식화 (stringify)

  ⍎¨ 각 실행 (평가) (숫자를 숫자로 얻습니다)

  () 다음과 같은 암묵적 기능을 적용하십시오.

   ⌈/ 가장 큰 숫자

   × 타임스

   10⊥ 베이스 10 디코딩 (숫자 수집)

    모든 숫자

   ⌷⍨¨ 각각에 의해 색인

   ⍳∘≢I 의 자릿수 ndices

    ~와 다르다

   ⊢⍳⌈/전체 자릿수 목록에서  가장 큰 자릿수 i ndex

   그것에 재귀 (즉 자기 호출)

 그밖에

   수정되지 않은 인수를 반환


>10>9?
Outgolfer Erik

@EriktheOutgolfer 아마, 그러나 OP는 실제로 그것에 대해 명확하지 않습니다 (자기 모순).
Adám

사실이지만 >9바이트를 절약 할 수 있습니다.
Outgolfer Erik

@EriktheOutgolfer가 업데이트되었습니다.
Adám

-1 바이트의 경우 ⍣ = 대신 @ Adám ∇ : {⍵> 9 : ∇ (⌈ / ... ⋄⍵}
ngn

3

펄 6 ,  45  41 바이트

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

그것을 테스트

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

그것을 테스트

넓히는:

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

레티 나 , 67 바이트

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

온라인으로 사용해보십시오! 링크에는 Dennis의 서버를 망치지 않을 정도로 빠른 테스트 사례가 포함됩니다. 설명:

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

두 자리 숫자의 경우이 숫자는 ;구분 기호로 숫자를 복제하고 앞에 1이 붙습니다. 한 자리 숫자의 경우이 숫자 앞에 숫자가 붙 1;습니다.

O`\G\d

중복의 자릿수를 정렬하십시오. 한 자리 숫자의 경우에는 효과가 없습니다.

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

가장 큰 숫자의 첫 번째 항목을 찾아서 삭제하십시오. 또한 중복 된 다른 숫자와 이전에 추가 된 여분의 1을 삭제하십시오. 한 자리 숫자의 경우 일치가 실패하므로 아무 것도 수행하지 않습니다.

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

숫자에 숫자를 곱하십시오. 한 자리 숫자의 경우 원래 숫자가되고 루프가 종료됩니다. 그렇지 않으면, 한 자릿수에 도달 할 때까지 프로그램이 반복됩니다.


3

C # (. NET 코어) , 177164 + 18 바이트

@raznagul 덕분에 13 바이트를 절약했습니다!

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

온라인으로 사용해보십시오!


당신은 변경할 수 있습니다 s.Length<2n<10. 또한 return f(y)사건이 if재귀의 다음 단계에서 처리 되므로 삼항 연산자를 제거 할 수 있습니다 .
raznagul

3

Java 8, 126104 바이트

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

@ OlivierGrégoire 덕분에 -22 바이트 .

설명:

여기에서 시도하십시오.

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 바이트 (위와 동일하지만 재귀 대신 반복적 인 : n>9및 대신 조건을 되돌리기 n<10).
Olivier Grégoire

2

Jq 1.5 , 86 바이트

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

넓히는

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
)

온라인으로 사용해보십시오!



2

루아, 137108 바이트

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

29 바이트를 포기한 Jonathan S에게 감사합니다.

온라인으로 사용해보십시오!



감사. 그것은 그 자신의 답변에 합당하게 보입니다-당신이 그것을 위해 작성한 게시물에 연결됩니다, 그렇지 않으면 편집 및 신용합니다.
MCAdventure10

그냥 편집하십시오. 그것은 여전히 ​​귀하의 코드이며, 처음부터 작성하지 않았습니다.
조나단 S.

2

, 188 (186) 185 바이트

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

온라인으로 사용해보십시오!

나는 게으른 평가가 너무 싫어. 모든 팁을 환영합니다!


2

루아, 154 바이트

골프를 치는 방법이 몇 가지 있습니다. 지금 실험 중입니다.

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)

온라인으로 사용해보십시오!

설명

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 바이트

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

온라인으로 사용해보십시오!

우프 PowerShell 배열은 변경할 [Collections.ArrayList]수 없으므로 .remove()나중에 호출 할 수 있도록 긴 캐스팅 을 사용해야합니다 .

input을 가져 $args와서 문자열로 변환 한 다음 char-array, 다음으로 변환합니다 ArrayList. 에 저장합니다 $a. 그런 다음 while에 또는 아래에 올 때까지 반복합니다 9. 반복 할 때마다 .remove가장 큰 요소를 호출 하고 $a( sort마지막 요소를 취하여 [-1]) 가장 큰 요소를$b 동시에 . 이것은 ASCII 값이 리터럴 숫자와 같은 방식으로 정렬되기 때문에 작동합니다.

다음으로, 우리는 다시 계산 $aint로서 다시 char(및 -array ArrayList우리의 주조에 의해 암시) $b(현재 인 char문자열에 다음 int로) +, 그리고에 있음을 곱하여$a -join 문자열로 에드 (암시 적 INT 캐스팅). 이는 챌린지의 "D 곱하기 D"부분을 만족시킵니다.

마지막으로 루프에서 벗어나 $a면 파이프 라인에 넣고 출력이 암시 적입니다.


2

, 22 21 바이트

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

입력을 명령 행 인수로 사용합니다. 모든 테스트 사례를 확인하십시오 : 온라인으로 사용해보십시오!

설명

코멘트가없는 언 골프 드 :

                 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

골프 버전에서 루프 바디는 단일 표현으로 압축됩니다.

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

자바 8 : 115 바이트


Jo King 덕분에 -10 바이트

불행하게도 람다 함수를 재귀 적으로 호출 할 수 없으므로 메소드 헤더에 11 바이트가 추가로 필요합니다. 루프가 짧아지는 Java 응답이 짧다는 것을 알고 있지만 혼자서 결정했습니다.

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

온라인으로 사용해보십시오


-48맵에서 m정의 의 끝으로를 이동할 수 있습니다 . 온라인으로 사용해보십시오! 또한 TIO 링크에 추가 공백이 있습니다
Jo King

@JoKing 감사합니다.
Benjamin Urquhart

1

J, 40 바이트

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

온라인으로 사용해보십시오!

설명

(      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
오늘 트리플 박스 선택에 대해 배웠습니다. 감사합니다!
Galen Ivanov

1

PowerShell , 230 바이트

$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

온라인으로 사용해보십시오!

모든 유형의 주조에서 너무 많이 낭비되었습니다.



1

dc , 98 85 바이트

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

많은 감사합니다 ~숫자에서 숫자를 추출하여 원래 버전의 코드보다 2 바이트를 절약 할 수 있다는 아이디어에 대한 이 답변 되었습니다 .

이것은 dc존재하지 않는 문자열 조작 기능 으로 완성하기는 다소 어렵습니다.

온라인으로 사용해보십시오!


1

배쉬, 80 바이트

핵심 유틸리티 (for sorttail) 및 패키지를 사용합니다 grep.

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

어떻게 작동합니까?

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`
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.