7로 나눌 수있는 규칙 구현


25

10 진수를 7로 나눌 수 있는지 확인하려면

마지막 숫자를 지 웁니다. 2를 곱하고 남은 것을 빼십시오. 결과를 7로 나눌 수있는 경우 원래 숫자는 7로 나눌 수 있습니다.

(또한 여기에 설명되어 있습니다 )

이 규칙은 수동 분할 검사에 적합합니다. 예를 들면 다음과 같습니다.

2016을 7로 나눌 수 있습니까?

덜다 6*2201에서 ; 우리는 189를 얻습니다. 이것은 7로 나눌 수 있습니까? 이를 확인하기 위해 규칙을 다시 적용 해 봅시다.

9*218에서 빼기 ; 우리는 0을 얻습니다. 따라서 2016은 7로 나눌 수 있습니다.

이 도전에서는 분할 상태가 명확 해질 때까지 , 즉 숫자가 70보다 크지 않을 때까지 (그러나 자세한 내용은 아래 참조) 이 규칙을 적용해야합니다 . 기능 또는 전체 프로그램을 작성하십시오.

입력 : 양의 정수; 코드는 최대 32767의 입력을 지원해야합니다 (임의의 정밀 정수 지원은 보너스입니다. 아래 참조).

산출 : 70보다 크지 않은 정수 (음수 일 수 있음), 이는 7로 나눈 규칙을 0 번 이상 적용한 결과입니다.

테스트 사례 :

Input                   Output      Alternative output

1                       1
10                      10          1
100                     10          1
13                      13          -5
42                      42          0
2016                    0
9                       9
99                      -9
9999                    -3
12345                   3
32767                   28          -14

---------- Values below are only relevant for the bonus

700168844221            70          7
36893488147419103232    32          -1
231584178474632390847141970017375815706539969331281128078915168015826259279872    8

두 개의 가능한 출력이 지정된 경우 두 결과 중 하나가 정확합니다. 두 번째 출력은 규칙을 한 번 더 적용하는 것에 해당합니다. 한 자리 숫자에 규칙을 적용하는 것은 금지되어 있습니다. 자리를 지우면 0이 아닌 것은 남지 않습니다.


보너스 : 알고리즘

어디에 n 십진수의 수는 다음과 같습니다.

코드의 바이트 수에서 50 %를 빼십시오.

실제 보너스 :

또한 알고리즘이 가장 중요한 자릿수부터 시작하여 정상 방향으로 입력을 읽는 경우 다시 50 %를 뺍니다. 점수는 바이트 수의 25 %입니다 (가능한 것 같지만 확실하지는 않습니다).


1
@DenkerAffe 입력을 그대로 반환하는 것은 허용됩니다. 이를 반영하기 위해 input = 10의 테스트 사례를 업데이트했습니다. 그것은 처음부터 아이디어였습니다.
anatolyg

4
에 해당 규칙을 사용하고 싶지 않습니다 1000000000000000000001.
Neil

1
그러나 언어에 long longs 또는 이와 동등한 유형이 내장되어 있으면 어떻게 됩니까?
SuperJedi224

1
내가 말한 것은 일부 구현에서는 128 비트 정수이며 마지막 테스트 사례에 비해 충분히 큽니다.
SuperJedi224

7
-1. 모든 언어가 임의의 정밀도를 지원하는 것은 아닙니다.
March Ho

답변:


23

골프 스크립트, 27 22 바이트

{.9>{.10/\10%2*-f}*}:f

이 방법으로 사용할 수 있습니다 :

1000f

설명

{.9>{.10/\10%2*-f}*}:f
{                  }:f    # Define block 'f' (similar to a function)
 .                        # Duplicate the first value of the stack
  9>{            }*       # If the value on top of the stack is greater than 9 then the block is executed
     .10/\10%2*-          # Same as nb/10 - (nb%10 * 2) with some stack manipulations '.' to duplicate the top of the stack and '\' to swap the the first and second element of the stack
                f         # Execute block 'f'

Dennis 덕분에 5 바이트가 절약되었습니다!


1
프로그래밍 퍼즐과 코드 골프에 오신 것을 환영합니다. 이것은 좋은 대답이지만 위의 질문과 같이 코드 분석 및 설명을 추가하여 개선 할 수 있습니다. 이 댓글을 입력에 댓글을 올리려면 @wizzwizz4( @(또는 어디에서) 주석의 시작 부분에 다음 사용자 이름).
wizzwizz4

1
@ wizzwizz4 더 좋습니까? '코드 분석'(원어민 미안)이 무슨 뜻인지 잘 모르겠습니다.
Dica

8
나는 "코드 분석"으로 당신이 추가 한 설명을 의미한다고 믿는다. 이것은 실제로 매우 좋은 첫 번째 대답입니다. 사이트에 오신 것을 환영합니다!
Alex A.

1
{...}{}if부품을로 다시 작성할 수 있습니다 . {...}*이 값은에 의해 푸시 된 값에 따라 코드 블록 0을 한 번만 적용합니다 >. 또한, 우리는 하나가 더 반복 (그래서 대체 수행 할 수있는 709바이트를 저장), 그리고 당신이 함께 블록을 팝업 필요가 있다고 생각하지 않습니다 ;.
Dennis

3
@Dica, 이것은 단지 624 번의 견해로 질문에 대해 12 명 이상의 공감대를 얻고 두 명의 중재자로부터 칭찬을받을 수있는 첫 번째 답변입니다. 이것을 유지하면 곧 데니스를 추월 할 것입니다!
wizzwizz4

13

하스켈, 35 바이트

until(<71)(\n->div n 10-2*mod n 10)

사용 예 : until(<71)(\n->div n 10-2*mod n 10) 36893488147419103232->32 .

설명 할 것이 많지 않은 것은 알고리즘을 직접 구현 한 것입니다.


9

젤리, 11 바이트

d⁵Uḅ-2µ>9$¿

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

작동 원리

d⁵Uḅ-2µ>9$¿  Main link. Input: n

d⁵           Divmod; return [n : 10, n % 10].
  U          Upend; yield [n % 10, n : 10].
   ḅ-2       Convert from base -2 to integer, i.e., yield -2 × (n % 10) + (n : 10).

      µ      Push the previous chain as a link and begin a new, monadic chain.
          ¿  Apply the previous chain while...
       >9$     its return value is greater than 9.

그리고 항상, 젤리가 이깁니다. Dennis, Jelly에서 젤리 인터프리터를 구현하는 데 얼마나 많은 바이트가 필요합니까?
Bálint

6

파이썬 2, 38 바이트

f=lambda x:f(x/10-x%10*2)if x>70else x

여기 사용해보십시오 !

간단한 재귀 접근. <<70 인 경우 x가 나눗셈 규칙을 적용하고 x를 인쇄하여 결과를 호출합니다.


당신은 다음에 공간이 필요하지 않습니다)
Maltysen

@Maltysen True입니다. 힌트를 붙여서 잘못된 것을 붙여 넣었습니다.
Denker

2
if가 너무 장황하다. f=lambda x:x*(x<70)or f(x/10-x%10*2)
seequ

1
@Seeq 좋은 트릭, 감사합니다! 이것은 이론적으로 작동하지만 2016 버전에서는 입력으로 2016을 사용하여 최대 재귀 깊이에 도달합니다. 왜 그런지 알아?
덴커

아, 맞아요. 이 트릭 x*(x<70) != 0은 최종 조건으로 간주 됩니다. x가 0에 도달하면 2016과 마찬가지로 종료 조건이 발생하지 않습니다.
seequ

6

Pyth, 13 바이트

.W>H9-/ZTyeZQ

온라인으로 사용해보십시오 : 데모 또는 테스트 스위트

모든 대체 답변이 인쇄됩니다.

설명:

.W>H9-/ZTyeZQ   
            Q   read a number from input
.W              while
  >H9              the number is greater than 9
                do the following with the number:
      /ZT          divide it by 10
     -             and subtract
         yeZ       2*(number%10)

5

줄리아, 27 26 바이트

f(x)=x>9?f(x÷10-x%10*2):x

정수를 허용하고를 반환하는 재귀 함수입니다 BigInt. 마지막 예제와 같이 입력이 큰 경우 Julia는 입력을로 구문 분석 BigInt하므로 수동 변환이 필요하지 않습니다.

이 접근법은 알고리즘의 간단한 구현입니다. 대체 출력을 생성합니다. 10으로 나눌 때 계수를 취하면 마지막 숫자가 산출되고 정수 나누기의 몫은 마지막 숫자를 제외한 모든 결과를 산출합니다.

Dennis 덕분에 바이트를 절약했습니다!


반복을 한 번 더 수행 할 수 있으므로으로 바꾸면 바이트 709절약됩니다.
데니스

@Dennis 좋은 전화 감사합니다!
Alex A.

4

Pyth, 17 바이트

L?<b70by-/bT*%bT2

여기 사용해보십시오!

파이썬 답변 과 같은 재귀 접근 방식 . 다음 y과 같은 람다 를 정의합니다 y12345.
온라인 인터프리터의 바이트 카운터는 람다 호출을 추가했기 때문에 19 바이트를 표시하므로 실행 버튼을 눌러 시도 할 수 있습니다.

설명

L?<b70by-/bT*%bT2

L                  # Defines the lambda y with the parameter b
 ?<b70             # if b < 70:
      b            # return b, else:
       -/bT*%bT2   # calculate b/10 - b%10*2 and return it

당신은 당신의 설명에 오타가, 17 70해야합니다 : P
FryAmTheEggman

4

CJam-19 바이트

작업 중 버전 :

r~A*{`)]:~~Y*-_9>}g

온라인 또는 버전 # 1 동안 사용해보십시오 .

r~{_9>}{`)]:~~Y*-}w

온라인 또는 버전 # 2 동안 사용해보십시오 .

r~{_9>}{_A/\A%Y*-}w

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

r~                     | Read and convert input
  A*                   | Multiply by 10 to get around "if" rule
     `                 | Stringify
      )                | Split last character off
       ]               | Convert stack to array
        :~             | Foreach in array convert to value
          ~            | Dump array
           Y*          | Multiply by 2
             -         | Subtract
              _        | Duplicate
               9>      | Greater than 9?
    {            }g    | do-while

3

Oracle SQL 11.2, 116 바이트

WITH v(i)AS(SELECT:1 FROM DUAL UNION ALL SELECT TRUNC(i/10)-(i-TRUNC(i,-1))*2 FROM v WHERE i>70)SELECT MIN(i)FROM v;

언 골프

WITH v(i) AS
(
  SELECT :1 FROM DUAL
  UNION ALL
  SELECT TRUNC(i/10)-(i-TRUNC(i,-1))*2 FROM v WHERE i>70
)
SELECT MIN(i) FROM v;

3

하스켈 157 192 184 167 159 147 138 + 5 바이트 - 50 % = 71.5 바이트

O (1) 공간, O (n) 시간, 단일 패스!

h d=d%mod d 10
d%r=(quot(r-d)10,r)
p![d]=d-p*10
p![d,e]=d#(e-p)
p!(d:e:f)|(b,a)<-quotRem(2*d)10,(q,r)<-h$e-a-p=(b+q)!(r:f)
m#0=m
m#n=n-2*m
(0!)

0![6,1,0,2]2016 년에 규칙을 적용 하려면 as 를 사용하십시오 . 즉, 가장 중요도가 가장 낮은 스트림 형식으로 숫자를 전달하십시오. 이런 식으로 O (1) 공간 복잡도를 갖는 규칙을 적용하여 숫자를 숫자 단위로 전달합니다.

ungolfed 코드는 다음과 같습니다.

import Data.Char

{- sub a b = sub2 0 a b
  where
    sub2 borrow (a:as) (b:bs) = res : sub2 borrow2 as bs
      where
        (borrow2, res) = subDig borrow a b
    sub2 borrow (a:as) [] = sub2 borrow (a:as) (0:[])
    sub2 _ [] _ = [] -}

--subDig :: Int -> Int -> Int -> (Int, Int)
subDig borrow a b = subDig2 (a - b - borrow)
  where
    subDig2 d = subDig3 d (d `mod` 10)
    subDig3 d r = ((r-d) `quot` 10, r)

seven ds = seven2 0 ds
seven2 borrow (d:e:f:gs) = seven2 (b + borrow2) (res:f:gs)
  where
    (a, b) = double d
    (borrow2, res) = subDig borrow e a
seven2 borrow (d:e:[]) = finalApp d (e-borrow)
seven2 borrow (d:[]) = d - borrow*10

double d = ((2*d) `mod` 10, (2*d) `quot` 10)

finalApp m 0 = m
finalApp m n = n - 2*m

num2stream :: Int -> [Int]
num2stream = reverse . map digitToInt . show
sev = seven . num2stream

이것이 어떻게 작동하는지의 요지는 그것이 자릿수 뺄셈 알고리즘을 하지만 빼는 각 숫자가 최대 2 자리수라는 사실을 이용 하므로이 1- 또는 주요 숫자에서 2 자리 숫자 (최하위 숫자를 먹는 것).

빼기 알고리즘은 O (1)이며 현재 '빌리'값만 저장합니다. 여분의 숫자 (0 또는 1)를 추가하기 위해 이것을 변경했으며,이 빌림 값이 제한되어 있음을 알았습니다 ([-2,2] 범위 내에 있으므로 이것을 저장하려면 3 비트 만 필요합니다).

메모리에 저장된 다른 값은 추가 할 현재 2 자리 숫자, 스트림의 단일 미리보기 및 감산 알고리즘의 한 단계 적용 (즉, 두 자리 숫자와 차용 값을 가져 와서 반환하는 임시 변수)입니다. 한 자릿수와 새로운 차용 가치).

마지막으로 스트림 목록의 마지막 두 자리를 한 번에 처리하여 숫자 목록이 아닌 한 자리 숫자를 반환합니다.

NB sevungolfed 버전 의 함수는에서 작동 Integer하여 반전 된 스트림 형식으로 변환합니다.


보너스는 일반적인 자릿수 순서를위한 것입니다. 그러나 나는 그것을 말한 적이 없으므로 재미가 떨어지더라도 역순으로 보너스를받는 것이 공정합니다. 어쨌든, 반대로 된 순서조차도 생각보다 어렵 기 때문에 충분히 재미 있습니다!
anatolyg

@anatolyg : 감사합니다! 정상적인 순서의 단일 패스 O (1) 구현을 수행 할 수 있는지 확실하지 않습니다 ... 규칙은 가장 중요하지 않은 수치에 따라 달라 지므로 이론적으로는 규칙을 역순으로 제외하고는 규칙을 직접 적용 할 수 없습니다. 내가 생각할 수있는 유일한 다른 것은 수학적으로 동등한 형식을 찾는 것입니다. 예를 들어 Mod[18 - Quotient[n, 10] - 2*n, 21] - 18 + Quotient[n, 10]10에서 99 사이의 n에 대해 경험적으로 작동하지만 n이 더 많은 자릿수를 가질수록 더 복잡해집니다.
nitrous

흠 나는 그것에 대해 생각했고 앞의 두 자리 숫자를 유지하고 각 후속 숫자를 적용하는 방법이있을 것 같지만 (-2) ^ n을 곱하여 '필터링'하는 것을 고려했습니다 ... 모든 숫자를 기억하고 O (1) 'ness 또는 심지어 o (n)'ness를 희생하지 않고이 작업을 수행 할 수있는 방법은 없지만 말할 수는 있습니다 ... 나는 정상적인 순서가 확실히 불가능하다고 생각합니다 :(
nitrous

1
0호출 할 때 이니셜의 바이트도 계산해야합니다 ( !예 : 섹션 (0!)(+ 줄 바꿈), 즉 + 5 바이트). 다른 한편 !으로 p![d]=and의 패턴 일치를 처음으로 단축 할 수 있습니다 p![d,e]=. 또한 let: 대신 패턴 가드를 사용 하십시오 p!(d:e:f)|(b,a)<-quotRem(2*d)10,(q,r)<-h$e-a-p=(b+q)!(r:f).
nimi

1
@nitrous : 오, 나는 (0!)그것의 자신의 라인에 ment . (0!)답으로 제공하는 기능입니다. 이 0필요하지만 입력 함께 할 수 없다, 그래서 당신은하지 그것은 아웃소싱 호출자에게 있습니다. 물론을 사용할 수도 f x=0!x있지만 이것은 더 깁니다.
nimi

3

GNU dc, 20 15 바이트

[10~2*-d70<F]sF

이것은 내 첫 번째 (모든) dc 함수를 정의합니다 F. 스택 맨 위에 입력을 취하고 출력을 스택 맨 위에 둡니다. 사용법 예 :

36893488147419103232
lFxp
32

2

매스 매 티카, 47 44 바이트

If[#>70,#0[{1,-2}.{⌊#/10⌋,#~Mod~10}],#]&

간단한 재귀 접근. 아마도 더 골프를 칠 수있을 것입니다.


#0[{1,-2}.QuotientRemainder[#,10]]바이트를 저장합니다.
njpipeorgan

2

R, 43 바이트

x=scan();while(x>70)x=floor(x/10)-x%%10*2;x

설명:

x=scan()                                      # Takes input as a double
        ;                                     # Next line
         while(x>70)                          # While-loop that runs as long x > 70
                      floor(x/10)             # Divide x by 10 and round that down
                                 -x%%10*2     # Substract twice the last integer
                    x=                        # Update x
                                         ;    # Next line once x <= 70
                                          x   # Print x

샘플 실행 :

> x=scan();while(x>70)x=floor(x/10)-x%%10*2;x
1: 9999
2: 
Read 1 item
[1] -3

> x=scan();while(x>70)x=floor(x/10)-x%%10*2;x
1: 32767
2: 
Read 1 item
[1] 28

1

자바 스크립트 ES6, 38 바이트

a=i=>i>70?a(Math.floor(i/10)-i%10*2):i

실패 36893488147419103232및 사용 ~~(1/10)도 실패합니다700168844221

테스트:

a=i=>i>70?a(Math.floor(i/10)-i%10*2):i
O.textContent = O.textContent.replace(/(-?\d+) +(-?\d+)/g, (_,i,o) =>
  _+": "+(a(+i)==o?"OK":"Fail")
);
<pre id=O>1                       1
10                      10
100                     10
13                      13
42                      42
2016                    0
9                       9
99                      -9
9999                    -3
12345                   3
700168844221            70
36893488147419103232    32</pre>


나는 두 개의 Fail... 70와 32를 얻는다
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ 그래, 그래도 왜 궁금해 ...
andlrc

JavaScript의 숫자 유형은 적어도 마지막 경우를 처리하지 않기 때문입니다.
코너 O'Brien

1
f=n=>n>70?f((n-n%10*21)/10):n는 더 짧은 버전이지만 여전히 최대 버전에서만 작동합니다 2**56.
Neil

@ Neil은 임의의 정밀도에 대한 내 대답을보고 골프에 자유롭게 느끼십시오.
패트릭 로버츠

1

수학, 33 바이트

#//.a_/;a>70:>⌊a/10⌋-2a~Mod~10&

테스트 사례

%[9999]
(* -3 *)

1

펄 5, 47 46 바이트

bigint마지막 테스트 사례 에 사용해야 했습니다. (없이 20을 반환)

use bigint;$_=<>;while($_>9){$_-=2*chop;}print

그것이 보너스의 후보인지 확실하지 않기 때문에 나는 그것을 고려하지 않았습니다. (그렇다고 생각하지만 실제로는 개념에 익숙하지 않습니다)

여기 사용해보십시오!


1

ES6, 108 바이트

f=(s,n=0)=>s>1e9?f(s.slice(0,-1),((1+s.slice(-1)-n%10)%10*21+n-s.slice(-1))/10):s>9?f(((s-=n)-s%10*21)/10):s

2²⁵⁷ 및 1000000000000000000001에서 작동하지만 추가 골프를 사용할 수 있습니다.


@PatrickRoberts 죄송합니다. 제출을 위해 형식을 다시 지정할 때 감독합니다.
Neil

1

자바 스크립트 ES6, 140 142 바이트

f=s=>s>9?eval("t=s.replace(/.$/,'-$&*2');for(i=-1;0>(n=eval(u=t[c='slice'](i-4)))&&u!=t;i--);n<0?n:f(t[c](0,i-4)+('0'.repeat(-i)+n)[c](i))"):s

이것은 진정한 임의 정밀도 수학이며 가장 큰 테스트 사례에서도 작동합니다.

이 함수는 문자열에서 마지막 숫자를 재귀 적으로 제거한 다음 차이가 양수가 될 때까지 minuend에 적용 할 숫자의 양을 반복적으로 증가시켜 나머지 숫자 문자열에서 2 * 마지막 숫자를 뺍니다. 그런 다음 적절하게 채워진 0s 를 사용하여 문자열 끝에 해당 차이를 추가 하고 숫자 값이보다 작거나 같을 때까지 재귀 적으로 호출합니다 9.

  • @Neil 덕분에 7 바이트가 골프를 쳤습니다 (예, 2 바이트를 얻었지만 함수가 멈추거나 일부 경우 잘못된 출력을 반환하는 몇 가지 버그가 수정되었습니다).

f=s=>s>9?eval("t=s.replace(/.$/,'-$&*2');for(i=-1;0>(n=eval(u=t[c='slice'](i-4)))&&u!=t;i--);n<0?n:f(t[c](0,i-4)+('0'.repeat(-i)+n)[c](i))"):s;[['1',1],['10',1],['100',1],['13',-5],['42',0],['2016',0],['9',9],['99',-9],['9999',-3],['12345',3],['700168844221',7],['36893488147419103232',-1],['231584178474632390847141970017375815706539969331281128078915168015826259279872',8]].map(a=>document.write(`<pre>${f(a[0])==a[1]?'PASS':'FAIL'} ${a[0]}=>${a[1]}</pre>`))


좋지만에 작동하지 않을 수 있습니다 1000000000000000000001.
Neil

1
시도하십시오 s.replace(/.$/,'-$&*2'). 미안하지만 나머지에 대한 명확한 아이디어는 없습니다.
Neil

1

C #, 111104 바이트

int d(int n){var s=""+n;return n<71?n:d(int.Parse(s.Remove(s.Length-1))-int.Parse(""+s[s.Length-1])*2);}

1

Brain-Flak , 368360 바이트

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

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

설명

모든 코드를 시작하려면 스택의 맨 위가 0보다 작을 때까지 실행되는 루프에 있습니다.

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

루프 안에서 7 개의 알고리즘으로 나눌 수 있습니다.

스택 상단 복제

(({}))

스택 상단의 mod 10을 취하십시오 (마지막 숫자)

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

이것은 약간 엉망이지만 나중에 설명 할 수있는 나머지 알고리즘을 수행하지만 작동 방식을 완전히 기억하지는 못합니다.

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

1

C, 56 바이트-75 % = 14

이것은 테스트 사례와 정확히 같은 숫자를 제공하지는 않지만 질문의 정신을 만족시킵니다 (그리고 틀림없이 더). 7의 정확한 배수를 정확하게 식별하고 음수를 사용하지 않기 때문에 다른 숫자에 대해 정확한 나머지를 제공합니다.

n;f(char*c){for(n=0;*c;)n-=n>6?7:'0'-n-n-*c++;return n;}

알고리즘에는 곱셈이나 나눗셈이없고 덧셈과 뺄셈 만 있으며 숫자는 왼쪽에서 오른쪽으로 한 번에 처리됩니다. 누산기에서 0으로 시작하여 다음과 같이 작동합니다.

  1. 필요한 경우 7을 빼고 여전히 필요한 경우 다시 빼십시오
  2. 누적 합계에 3을 곱하고 다음 숫자를 더하십시오.

"3의 곱하기"단계는 n-=-n-n바이트를 저장하고 곱하기 연산자를 피하기 위해 작성됩니다 .

우리가 끝을 칠 때, 우리는 7을 빼지 않으므로 결과는 0-24의 범위에있을 것입니다; 당신이 엄격한 계수 (0-7)하려면, 대신 *c*c||n>6for 루프 조건을.

강화 된 보너스를받을 자격이 있습니다.

  • 임의 정밀도 정수 지원
  • 입력을 왼쪽에서 오른쪽으로 한 번만 수행합니다.
  • 공간 복잡도 O (1)
  • 시간 복잡도 O (n).

테스트 프로그램 및 결과

#include <stdio.h>
int main(int argc, char **argv) {
    while (*++argv)
        printf("%s -> %d\n", *argv, f(*argv));
    return 0;
}
540 -> 15
541 -> 16
542 -> 17
543 -> 18
544 -> 19
545 -> 20
546 -> 21
547 -> 22
548 -> 23
549 -> 24
550 -> 18
99 -> 15
999 -> 12
12345 -> 11
32767 -> 7
700168844221 -> 7
36893488147419103232 -> 11
231584178474632390847141970017375815706539969331281128078915168015826259279872 -> 11

대체 버전

다음은 되풀이되는 것입니다 (컴파일러 최적화를 사용하여 테일 콜 변환을 수행하거나 스택을 오버플로 할 수 있습니다 gcc -std=c89 -O3).

f(c,n)char*c;{return n>6?f(c,n-7):*c?f(c+1,n+n+n+*c-'0'):n;}

두 번째 인수로 '0'을 사용하여 호출하십시오.

두 버전 모두 내 컴퓨터에서 50 밀리 초 미만의 60,000 자리 숫자 중 나머지 모듈로 -7을 계산합니다.


보너스에 감사드립니다-C가 경쟁력을 갖도록 실질적인 변화를 가져옵니다! 현재 Jelly (11)와 Pyth (13) 만이 이겼습니다 . :-)
Toby Speight

1

PHP, 50 바이트

for($n=$argv[1];$n>9;)$n=$n/10|0-2*($n%10);echo$n;

대체 출력을 사용합니다. 까지 작동PHP_INT_MAX


문자열 버전, 모든 (양수) 숫자 (64 바이트)에 대해 작동합니다.

for($n=$argv[1];$n>9;)$n=substr($n,0,-1)-2*substr($n,-1);echo$n;

0

자바, 133 바이트

int d(int n){String s=""+n;return n<71?n:d(Integer.parseInt(s.replaceFirst(".$",""))-Integer.parseInt(""+s.charAt(s.length()-1))*2);}

나는 얼마나 장황한가 싫어 Integer.parseInt. 언 골프 드 :

static int div(int n) {
    if (n <= 70) {
        return n;
    } else {
        String num = ("" + n);
        int last = Integer.parseInt("" + num.charAt(num.length() - 1));
        int k = Integer.parseInt(num.replaceFirst(".$", "")) - last * 2;
        return div(k);
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.