나누고 나누고 정복하십시오


22

때때로, 내가 숫자 앞에 어떤 숫자가 나오는지 알아 내려고 할 때 ¹, 잠시 후에 생각보다 쉽다는 것을 깨달았습니다. 가지고 2156예를 들면 : 결국 모두 나에게 발생 21하고 56의 배수는 7, 그래서 확실히 2156 = 21 x 100 + 56도의 배수입니다 7.

당신의 임무는 이러한 종류의 우연의 일치로 인해 더 쉽게 숫자를 식별하는 코드를 작성하는 것입니다.

더 정확하게:

양수 얻어 프로그램이나 함수 작성 n입력으로, 그리고 제수에게 존재하는 경우 truthy 값을 반환 d(이상 1등) n의 배수이고, 각각의 두 개의 양의 정수를 산출하기 위해 두 다진 수 d; 그렇지 않으면 거짓 값을 반환합니다.

  • "두 개로 나"다 "는 당신이 생각하는 것을 의미합니다 : n어떤 점에서 앞면 반과 뒷면 반으로 나누어 져서 두 개의 다른 10 진 정수를 만들어냅니다. 두 번째 정수 (이 양의 정수이어야하지만 참고 분할 있도록 앞에 0이있는 경우 괜찮아 1230으로 123하고 0유효하지 않습니다).
  • 진실되고 잘못된 값은 입력에 따라 달라질 수 있습니다. 예를 들어, 0이 아닌 정수가 선택한 언어에서 진실한 경우, 제수 d또는 " n또는 n그 문제 "중 하나 를 반환 해도됩니다.
  • 예를 들어, 세트에 두 자리 이상의 숫자가 {2, 4, 6, 8}있는 짝수는 정확한 값을 산출합니다. 첫 번째 짝수 자리 이후에 나누면됩니다. 또한 예를 들어 소수n 는 모든 한 자리 숫자와 마찬가지로 잘못된 값을 생성합니다.
  • 소수의 제수를 고려하면 충분합니다 d.
  • 입력이 유효하다고 가정 할 수 있습니다 (즉, 양의 정수).

이것은 이므로 바이트 단위의 가장 짧은 코드가 이깁니다. 그러나 모든 언어의 솔루션을 환영하므로 전체적으로 가장 짧은 코드뿐만 아니라 각 언어의 가장 짧은 코드를 위해 노력할 수 있습니다.

테스트 사례

(진실하거나 허위 인 값만 출력하면됩니다. 아래 주석은 설명을위한 것입니다.) 진지한 값을 산출하는 일부 입력은 다음과 같습니다.

39  (3 divides both 3 and 9)
64  (2 divides both 6 and 4)
497  (7 divides both 49 and 7)
990  (splitting into 99 and 0 is invalid; but 9 divides both 9 and 90)
2233  (11 divides both 22 and 33)
9156  (3 divides both 9 and 156; or, 7 divides both 91 and 56)
11791  (13 divides both 117 and 91)
91015  (5 divides both 910 and 15)
1912496621  (23 divides both 1912496 and 621; some splittings are multiples of 7 as well)
9372679892  (2473 divides both 937267 and 9892; some splittings are multiples of 2 as well)

허위 값을 산출하는 일부 입력은 다음과 같습니다.

52
61
130  (note that 13 and 0 is not a valid splitting)
691
899
2397
9029
26315
77300  (neither 7730 and 0 nor 773 and 00 are valid splittings)
2242593803

¹ 네, 이거 정말 해요

답변:


7

망막 , 31 29 바이트


,$';$`
\d+
$*
;(11+)\1*,\1+;

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

유효한 입력의 경우 양의 정수를 출력하고 유효하지 않은 입력의 경우 0을 출력합니다.

더 큰 테스트 사례를 기다리는 것은 좋지 않습니다 ...

설명


,$';$`

입력의 각 위치에 쉼표를 입력 한 다음 해당 위치 이전의 모든 항목, 세미콜론,이 위치 이후의 모든 항목을 삽입하십시오. 그게 뭐에요? 그것은 우리에게 숫자의 가능한 모든 분리 (으로 분리 ,,로 분리 ;)를 제공 한 다음 끝에 입력을 다시 제공합니다. 입력 123

,123;1,23;12,3;123,;123
     ^     ^     ^

원래 입력 문자를 표시했습니다 (표시되지 않은 것은 삽입 한 것입니다). 이렇게하면 실제 분할이 아닌 잘못된 분할이 생성되고 후행 구성 요소가 모두 0인지 여부는 신경 쓰지 않지만 나중에 수락하지는 않습니다. 유효하지 않은 분할을 만들면 각각의 유효한 분할이 ;앞뒤에 있다는 것을 알고 있으므로 워드 경계에서 2 바이트를 절약 할 수 있습니다.

\d+
$*

각 숫자를 단항으로 변환하십시오.

;(11+)\1*,\1+;

두 반쪽을 2 이상의 배수로 일치시켜 분할을 일치시킵니다.


Retina에 대한 빠른 질문 : 주요 개행은 무엇을합니까?
HyperNeutrino

@HyperNeutrino 첫 번째 줄은 첫 번째 정규 표현식이며, 빈 정규 표현식과 일치하여 문자 사이의 모든 단일 위치에 대체를 삽입하려고합니다.
Martin Ender

오 알았어 감사! 아마 Retina를 조금 더 살펴 봐야합니다. 그것은 정규 표현식 기반으로 보이 므로 kolmogorov 복잡성 문제에 도움이 될 수 있습니다 .
하이퍼 뉴트리노

마지막 줄이 될 수 있을까 ;(11+)+,\1+;
Riley

@Riley는 첫 번째 세그먼트가 동일한 요소의 배수임을 보장하지 않습니다.
Martin Ender

6

Brachylog (2), 8 바이트

~c₂ḋᵐ∋ᵐ=

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

설명

~c₂ḋᵐ∋ᵐ=
~c₂       Split the input into two pieces
    ᵐ ᵐ   On each of those pieces:
   ḋ ∋      Choose a prime factor
       =  such that both the chosen factors are equal

동일한 숫자 (1보다 큰 숫자)가 두 조각 을 나누면 동일한 소수가 두 조각 을 나눕니다. 요인을 소수로 요구하면 1을 요인으로 깔끔하게 허용하지 않습니다. 또한 리터럴 0이 숫자의 세그먼트로 선택되는 것을 방지합니다 ( 0소인수 분해가 없으므로 실패 할 수 있음).

내부 0과 일치하는지 확인할 필요가 없습니다. 의 분할 경우 x와는 0y유효 x0하고 y단지뿐만 아니라 작동합니다 (그리고 경우, 다른 방법을 가고 x0y작품, 우리는 여부에 관계없이의 작업 솔루션을 x하고 0y일을하거나하지 않을).

이와 같은 Brachylog 전체 프로그램은 부울을 리턴합니다. 모든 경로가 실패로 이어질 경우 true.실패없이 실행할 수있는 방법이있는 경우 (즉, 오류가 발생하지 않도록 선택) false.. 그것이 바로 우리가 원하는 것입니다.


4

젤리 , 14 12 11 10 바이트

ŒṖḌo1g/€P>

1 바이트를 골프로 해준 @JonathanAllan에게 감사합니다!

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

작동 원리

ŒṖḌo1g/€P>  Main link. Argument: n

ŒṖ          Compute all partitions of n's decimal digits.
  Ḍ         Undecimal; convert each array in each partition back to integer.
   o1       OR 1; replace disallowed zeroes with ones.
     g/€    Reduce (/) each (€) partition by GCD (g).
            The last GCD corresponds to the singleton partition and will always be
            equal to n. For a falsy input, all other GCDs will be 1.
        P   Take the product of all GCDs.
         >  Compare the product with n.

에 대한 효과는 D그대로 떨어 뜨릴 수 있다고 생각합니다 . make_digitsŒṖ
Jonathan Allan

어떤 이유로, 나는 범위를 만들 것이라고 가정했습니다 ... 감사합니다!
Dennis

3

Mathematica, 63 62 바이트

(Greg Martin 덕분에 1 바이트)

1<Max@@GCD@@@Table[1~Max~#&/@Floor@{Mod[#,t=10^n],#/t},{n,#}]&

정수를 입력으로 받아 반환하는 함수입니다. True 또는 False. 큰 숫자로 테스트하는 경우 기다리는 동안 읽을 책을 가져 오십시오.

설명:

  • Floor@{Mod[#,t=10^n],#/t}입력을 마지막 n숫자와 나머지 로 산술적으로 분할m-n 숫자 (여기서m 총 자리 수) .
  • Table[1~Max~#&/@...,{n,#}]n입력 번호까지 모든 작업을 수행합니다. (이 방법은 너무 큽니다. 입력 의 자릿수 까지만 수행하면 되지만이 방법으로 바이트를 절약하고 여전히 올바른 결과를 얻을 수 있습니다.) 1~Max~#&/@비트는 0을 제거하므로 숫자는 다음과 같습니다.130 -> {13,0} 는 계산되지 않습니다. 같이True .
  • 1<Max@@GCD@@@... 이 쌍 각각의 최대 공약수를 찾고이 제수가 1보다 큰지 확인합니다. 만약 그렇다면, 우리는 숫자를 나누면 수를 인수 분해 할 수있는 방법을 찾았습니다.

1
좋은 대답입니다! {#~Mod~10^n,#/10^n}또는로 하나의 바이트를 저장할 수 있습니다 {Mod[#,t=10^n],#/t}.
Greg Martin

나는 시도 #~Mod~10^n했지만 Mod[#,10]^n대신에 대괄호로 보이는 것처럼 보인다 Mod[#,10^n]. 그래도 두 번째 제안은 생각하지 않았습니다!
나무가 아님

페어 포인트Mod[#,10]^n
Greg Martin


2

C, 145 142 139 138 135 바이트

i,a,b;f(){char s[99];scanf("%s",s);for(char*p=s;*p++;)for(b=atoi(p),i=*p,*p=0,a=atoi(s),*p=i,i=1;i++<b;)*s=a%i-b%i|b%i?*s:0;return!*s;}

2

자바 스크립트 (ES6), 74 71 70 바이트

f=(s,t='',u)=>u?s%t?f(t,s%t,1):t:s&&f(t+=s[0],s=s.slice(1),1)>1|f(s,t)
<input oninput=o.textContent=f(this.value)><span id=o>

스 니펫에 편리한 문자열로 입력을받습니다. 편집 : @ user81655 덕분에 3 바이트가 절약되었습니다.


(c,i)-> c, i+1-> ++i, t=''-> 두 바이트를 저장합니다. i=t=''이 트릭은 1 기반 인덱스를 사용해야하고 초기화 i할 위치가있을 때 유용합니다 0.
user81655

또한 어쨌든 문자열에 강제로 추가하기 때문에 t=''될 수 있다고 생각 합니다. t=0c
user81655

@ user81655 이것은 원래부터 and로 슬라이스했기 때문에 발생했기 때문에 i1 기반 인덱스가 필요하지 않았지만 첫 번째 슬라이스를로 골프를 쳤습니다 t+=c.
Neil

그래. 또한 마지막으로, 이것이 재귀 함수로서 짧을 수도 있다고 생각합니다 f=(x,y,z)=>z?x%y?g(y,x%y):y:x?f(x,y,1)>1||f(x.slice(1),~~y+x[0]):0. 나는 당신의 GCD 기능과 결합했습니다 f. 아마도 더 골프를 칠 수있을 것입니다. 마지막 제안, 약속합니다! : P
user81655

@ user81655 슬프게도 지나치게 단순화 된 gcd함수는 작동하지 않으며 x=0그 주위를 둘러 보면 오타가 72 바이트로 나를 데려 갔으므로 2 바이트를 골라 낼 수 있었던 것은 운이 좋았습니다.
Neil

2

파이썬 3 133 118 117 바이트

i,j=int,input()
from fractions import*
print(any(i(j[k:])*i(j[:k])*~-gcd(i(j[k:]),i(j[:k]))for k in range(1,len(j))))

확실히 가장 짧은 것은 아니며 아마도 조금 단축 될 수 있습니다. 제 O(n)시간에 작동 합니다. 입력은 형식으로 취해 \d+지고 출력은 (True|False)기본적으로 파이썬에 따라 형식 으로 제공
됩니다. Dead Possum 덕분에 -3 바이트-이
바이트 덕분에 ovs
-1 바이트 덕분에 -15 바이트


from fractions import*3 바이트를 절약합니다
Dead Possum

900에 대해 True를 반환합니다. 맞습니다. Mb 내부 anyall?로 변경해야 합니다 . 이 경우 해당 부분을 i(j[k:])and i(j[:k])모두 125 바이트 로 가져 오도록 변경할 수 있습니다 . 수정 사항
Dead Possum

곱셈으로 and를 모두 대체 할 수 있습니다.any(i(j[k:])*i(j[:k])*~-gcd(i(j[k:]),i(j[:k]))for k in range(1,len(j)))
ovs

@DeadPossum 아, 그래야 했어요. 그리고 예, 현재의 방법에는 많은 골프 용 부품이 있지만 ovs의 제안을 따르겠습니다. 지적 해 주셔서 감사합니다! (실제로 직접 테스트해야합니다 ... 오 잘 ...)
HyperNeutrino

당신은 사이의 공백 제거하여 바이트 (거의 아무것도)를 제거 할 수 있습니다)) for
coinheringaahing 케어 드

1

QBIC , 91 90 바이트

;_LA|[a-1|B=left$(A,b)┘C=right$(A,a-b)┘x=!B!┘y=!C![2,x|~(x>1)*(y>1)*(x%c=0)*(y%c=0)|_Xq}?0

설명:

;               Get A$ from the command prompt
_LA|            Get the length of A$ and place it in a% (num var)
[a-1|           for b%=1; b% <= a%-1; b%++
B=left$(A,b)    break A$ in two components on index b%
C=right$(A,a-b)
x=!B!┘y=!C!     Convert both parts from string to num, assign to x% and y%
[2,x|           FOR c% = 2; c% <= x%; c%++

This next IF (~ in QBIC) is a bit ... iffy. It consists of a set of comparators.
Each comparator yields a -1 or a 0. We take the product of these. At any failed
comparison this will yield 0. When successful, it yields 1, which is seen as true by QBasic.

~(x>1)*(y>1)        IF X>1 and Y>1 --> this stops '00' and '1' splits.
*(x%c=0)*(y%c=0)    Trial divide the splits on loop counter c%.

|_Xq            Success? THEN END, and PRINT q (which is set to 1 in QBIC)
}               Close all language constructs (2 FOR loops and an IF)
?0              We didn't quit on match, so print 0


1

펄 5 , 46 바이트

-p플래그 43 바이트 + 플래그 3 바이트

s~~$\|=grep!($`%$_|$'%$_),2..$`if$`*$'~ge}{

온라인으로 사용해보십시오! 또는 여러 입력을 허용하는 이 수정 된 버전을 사용해보십시오 .
시간이 오래 걸릴 수 있으므로 가장 큰 입력에서 시도하지 않을 수도 있습니다.

설명 :
s~~~g(과) 뒤에 $`숫자 를 포함하여 와 함께 단어의 각 위치를 반복합니다 $'. 경우 $`*$'(이것은 그 누구도 빈 없음을 의미하고, 아무도없는 사실이다 0), 우리는 2 사이의 숫자 있는지 확인 $`분할 둘 다의합니다 (과 grep!(...),2..$`)를. 그렇다면 0이 아닌 값으로 $\|=..설정 $\되어 -p플래그 덕분에 끝에 암시 적으로 인쇄됩니다 .


2
누군가 $<backquote>SE 마크 다운 을 렌더링하는 방법을 알고 있다면 방법을 알려 주면 감사 할 것입니다.
Dada

1
명시 적 <code></code>(대신 ``) 을 사용 하여 백 따옴표를로 이스케이프 처리하면됩니다 \`. 또한이 의견은 두 번 이스케이프 처리해야하기 때문에 작성하기가 어려웠습니다 (두 세트의 이스케이프 규칙이 다릅니다!).

@ ais523 정말 고마워요! :)
다다

0

파이썬 2 , 69 바이트

f=lambda n,d=10,k=2:k<d<n and(n/d%k+n%d%k<1<n%d)|f(n,d,k+1)|f(n,10*d)

내장 된 GCD 대신 재귀를 사용합니다.

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

작동 원리

f 가 1 ~ 3 개의 인수 ( d의 기본값은 10 , k ~ 2 ) 로 호출 되면 먼저 표현식 값을 확인합니다 k<d<n. 부등식 k <dd <n이 모두 유지되면 다음 표현식 and이 실행되고 해당 값이 리턴됩니다. 그렇지 않으면 f 는 단순히 False 를 반환합니다. 합니다.

전자의 경우 식을 평가하는 것으로 시작합니다 n/d%k+n%d%k<1<n%d.

D는 항상 10의 거듭 제곱이 될 것입니다 n/dn%d효과의 진수 분할 N을 두 조각으로. 이 슬라이스는 0으로 평가되는 경우에만 k 로 나눌 수 있으며 , 결과를 1 과 비교하여 테스트합니다 .n/d%k+n%d%k

요구 사항의 일부는 두 슬라이스 모두 양의 정수를 나타내야하므로 값 n%d1 과 비교됩니다 . 참고 1 에는 주요 약수가없는, 그래서 함께 더 비싼 비교 0이 필요하지 않습니다. 또한 d <n은 이미 n/d양의 정수로 평가되도록합니다.

마지막으로 재귀 적으로 f(n,d,k+1)(다음 잠재적 공통 제수를 f(n,10*d)시도 ) 및 (분할을 시도) 세 결과의 논리합을 반환합니다. 즉, f 는 다음 과 같은 경우에만 true 를 반환합니다. k는 의 공약수 인 N / D%의 D, N 또는 동일의 더 큰 값에 해당하는 K 및 / 또는 10 고전력 D .

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