binarray를 찾으십시오!


24

binarray 를 다음 속성을 만족하는 배열로 정의 합니다.

  • 비어 있지 않다
  • 첫 번째 값은 1
  • 마지막 값은 1
  • 다른 모든 값은 0또는1

예를 들어, 배열 [ 1, 1, 0, 1 ]은 유효한 binarray 입니다.

작업

비어 있지 않은 배열을 감안할 때 음이 아닌 정수의 정수 긍정적 인 N , 당신의 작업이 찾는 것입니다 binarray B 길이의 N 생성 할 수 있습니다 사본의 무제한 수를 합산하여 B를 ,의 무제한 번호로 이동 위치.

A = [ 1, 1, 2, 4, 1, 2, 2, 1, 0, 1, 0, 1, 1, 0, 1 ]
N = 4

이 입력의 경우 binarray B = [ 1, 1, 0, 1 ] 는 다음 과 같이 할 수 있기 때문에 올바른 대답이됩니다.

  [ 1, 1, 0, 1 ]
+       [ 1, 1, 0, 1 ]
+       [ 1, 1, 0, 1 ]
+          [ 1, 1, 0, 1 ]
+                   [ 1, 1, 0, 1 ]
+                                  [ 1, 1, 0, 1 ]
  -----------------------------------------------
= [ 1, 1, 2, 4, 1, 2, 2, 1, 0, 1, 0, 1, 1, 0, 1 ]

규칙

  • 적절한 형식으로 입력 할 수 있습니다.
  • 출력은 기본 배열 (예 [1, 1, 0, 1]:) "1,1,0,1"이거나 구분 기호가 있거나없는 이진 문자열 (예 : 또는 "1101") 일 수 있습니다.
  • 유효한 binarray 하나만 인쇄하거나 반환 하면 됩니다. 또는 여러 솔루션이있는 경우 모두 인쇄하거나 반환하도록 선택할 수 있습니다 .
  • 솔루션으로 이어지지 않는 입력을 지원할 필요는 없습니다.
  • 합은 B의 사본과 겹치지 않는 암시 적 0을 포함 할 수 있습니다 . 위의 합계에서 두 번째 0은 암시 적 0입니다.
  • A 의 최대 크기 는 100이고 B 의 최대 크기 는 30 이라고 가정 할 수 있습니다 .
  • 이것은 코드 골프이므로 바이트 단위의 최단 답변이 이깁니다. 표준 허점은 금지되어 있습니다.

테스트 사례

Input : N = 1 / A = [ 1, 2, 3, 4, 5 ]
Output: [ 1 ]

Input : N = 2 / A = [ 1, 2, 100, 99 ]
Output: [ 1, 1 ]

Input : N = 3 / A = [ 1, 1, 1 ]
Output: [ 1, 1, 1 ]

Input : N = 3 / A = [ 1, 1, 3, 2, 2 ]
Output: [ 1, 1, 1 ]

Input : N = 3 / A = [ 1, 0, 2, 1, 1, 1, 0, 0, 1, 0, 1 ]
Output: [ 1, 0, 1 ]

Input : N = 4 / A = [ 1, 2, 2, 2, 1 ]
Output: [ 1, 1, 1, 1 ]

Input : N = 4 / A = [ 1, 1, 2, 4, 1, 2, 2, 1, 0, 1, 0, 1, 1, 0, 1 ]
Output: [ 1, 1, 0, 1 ]

Input : N = 4 / A = [ 1, 1, 0, 2, 1, 0, 1 ]
Output: [ 1, 0, 0, 1 ] or [ 1, 1, 0, 1 ]

Input : N = 5 / A = [ 1, 3, 6, 9, 8, 6, 3, 4 ]
Output: [ 1, 1, 1, 0, 1 ]

Input : N = 8 / A = [ 2, 1, 0, 2, 3, 3, 1, 2, 1 ]
Output: [ 1, 0, 0, 1, 1, 1, 0, 1 ]

Input : N = 10 / A = [ 1, 2, 1, 2, 2, 1, 3, 3, 3, 2, 3, 0, 2, 1, 1, 0, 1 ]
Output: [ 1, 1, 0, 1, 0, 1, 1, 1, 0, 1 ]

Input : N = 13 / A = [ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 ]
Output: [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ]

Input : N = 5 / A = [ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 ]
Output: [ 1, 1, 1, 1, 1 ]

Input : N = 6 / A = [ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 ]
Output: [ 1, 0, 0, 0, 0, 1 ]

Input : N = 7 / A = [ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 ]
Output: [ 1, 1, 0, 0, 0, 1, 1 ]

Input : N = 9 / A = [ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 ]
Output: [ 1, 0, 1, 0, 1, 0, 1, 0, 1 ]

N합리적으로 지원되어야 하는 가장 큰 가치는 무엇입니까 ?
Neil

@ 닐 A와 B 모두에 크기 제한을 추가했습니다.
Arnauld

1
@ fənɛtɪk 어쩌면하지만, 대한 N=4, A = [ 1, 1, 2, 4, 1, 2, 2, 2, 1, 2, 2, 1, 2, 0, 1 ], 당신은 모두 11 아직 13 단 하나의로 나누어 30,459 얻을 [ 1, 1, 0, 1 ]하고 [ 1, 0, 1, 1 ]유효한 대답이다.
Neil

1
@ fəˈnɛtɪk이 숫자는 밑면 2로 작성되지 않았으므로 산술 규칙이 적용되지 않습니다. 예를 들어, 추가 할 때 명시 적으로 운반 할 수 없습니다.
BallpointBen

2
다음과 같은 테스트 사례를 추가하십시오. 게시 된 거의 모든 답변을 깰 것 같습니다 : N = 3, A = [1, 0, 2, 0, 2, 0, 1], 출력 = [1, 0, 1]; N = 3, A = [1, 1, 1, 0, 0, 0, 1, 1, 1], 출력 = [1, 1, 1].
Anders Kaseorg 2016 년

답변:


8

PHP, 105 92 90 86 바이트

Jörg의 솔루션 고정 및 골프 :

for($b=1+2**$argv[1];;)--$argc>1?$s+=$argv[$argc]*2**$i++:$s%($b-=2)||die(decbin($b));

N첫 번째 명령 줄 인수에서 그 이후의 값을 가져 옵니다. 온라인으로 실행 -r하거나 테스트하십시오 .
이진수를 인쇄합니다 (형식 10001). 유효하지 않은 솔루션을 인쇄하거나 유효한 솔루션이 없으면 작동하지 않습니다.

유효하지 않은 입력을 위해 아무것도 인쇄하지 않는 첫 번째 버전 (현재 97 바이트) : 온라인으로 테스트

for($b=1+$m=2**$argv[1];$m/2<=$b;)--$argc>1?$s+=$argv[$argc]*2**$i++:$s%($b-=2)||die(decbin($b));

고장

for($b=1+$m=2**$argv[1];$m/2<=$b;)  # second loop: loop $b from 2^N-1 by -2 to 2^(N-1)
--$argc>1                           # first loop: decrease $argc ...
    ?$s+=$argv[$argc]*2**$i++           # while $argc>1: binary sum from last to 2nd argument
    :$s%($b-=2)||die(decbin($b));       # later: if $b divides $s, print in binary and exit

100 미만의 바이트 수에 도달 할 수 없었습니까?
Jörg Hülsermann 2016 년

1
@ JörgHülsermann 할 수있었습니다.
Titus

심한 생각. 나는 이것보다 당신이 더 낫다는 것을 알고 있습니다. 난 당신이 가장 낮은 바이트 수를 보유 할 수 있기를 바랍니다
요 르그 Hülsermann

1
N = 3, A = [1, 0, 2, 0, 2, 0, 1]에서 올바른 결과 만 [1, 0, 1] 인 경우 잘못 반환111 됩니다.
Anders Kaseorg

8

PHP , 219 바이트

<?for(list($g,$z)=$_GET,$d=~-$l=2**$z;$d>=$l/2;max(array_diff_assoc($r,$g)?:[0])?:$o[]=$b,$d-=2)for($r=[],$b=decbin($d),$k=0;$k<count($g);$k++)for($u=$g[$k]-$r[$k],$i=0;$i<$z;$i++)$u<1?:$r[$k+$i]+=$u*$b[$i];print_r($o);

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

[$g,$z]=$_GETPHP 7.1 대신 -4 바이트list($g,$z)=$_GET


마지막 테스트 사례에 대해 유효한 ( [1,0,1,0,1,0,1,0,1]) 및 잘못된 답변 ( [1,0,0,0,1,0,1,1,1])을 모두 출력하는 것 같습니다 .
Arnauld

-8 바이트 : while($_GET[0])$s+=2**$i++*array_pop($_GET[0]);. -5 바이트 : range(1|.5*$m=2**$_GET[1],$m,2).
Titus

@Arnauld 예 나는이 솔루션을 유효하게 만들기 위해 가장 높은 binarray 만 출력으로 제공해야합니다.
Jörg Hülsermann

2
@ fəˈnɛtɪk 나는 당신의 수학에 동의하지만 도전은 동등한 배열이 아니라 A에 정확히 합칠 수있는 패턴을 찾는 것입니다. 여기, 우리는 얻을 [ 1,0,1,1,1,0,2,2,2,2,2,1 ]것이다.
Arnauld

1
와 -1 바이트 for($g=$_GET[0];$g;).
Titus

3

파이썬, 166 바이트

def f(a,n):
 for i in range(1<<n-1,1<<n):
  b=bin(i)[2:];u,v=(int(('0{:0>%d}'%sum(a)*len(s)).format(*s))for s in[a,b])
  if u%v<1>int(str(u//v*10)[::~sum(a)]):yield b

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

작동 원리

기본 k 숫자 uv 의 숫자로 A 및 B를 고려하십시오 . 예를 들어 설명을 위해 k = 1000을 사용합니다 .

A = [1, 2, 1, 3, 2, 1, 2]
B = [1, 0, 0, 1]
u = 1 002 001 002 002 001 002
v = 1000000 001

다른 많은 응답자들이 알았 듯이 B가 유효한 답이면 uv 로 나눌 수 있습니다. 이 경우

u = 1 002 001 002 ⋅ v

배열 [1, 2, 1, 2]로 다시 변환 된이 몫은 우리가 각 위치로 얼마나 많은 B의 사본을 이동했는지 알려줍니다.

  [1, 0, 0, 1]
+    [1, 0, 0, 1]
+    [1, 0, 0, 1]
+       [1, 0, 0, 1]
+          [1, 0, 0, 1]
+          [1, 0, 0, 1]
-----------------------
  [1, 2, 1, 3, 2, 1, 2]

(왜? 왜냐하면 그것은 기초 k 에서 곱셈이 정확히 얼마나 오래 걸리기 때문 입니다.)

다른 응답자가 알아 차리지 못한 것은 위의 조건이 충분하지 않다는 것 입니다. 예를 들면 다음과 같습니다.

A = [1, 2, 1, 3, 2, 1, 2]
B = [1, 1, 1, 1]
u = 1 002 001 002 002 002 001
v = 1 001 001 001
u = 1000 999 002 ⋅ ⋅ V

수학적으로 말해서, 그 몫을 배열 [1, 1, -1, 2]로 다시 변환 할 수 있습니다. B의 음수 복사본을 사용할 수 있다면 제대로 작동합니다.

  [1, 1, 1, 1]
+    [1, 1, 1, 1]
       [1, 1, 1, 1]
+          [1, 1, 1, 1]
+          [1, 1, 1, 1]
-----------------------
  [1, 2, 1, 3, 2, 1, 2]

그러나 당면 과제는 부정적인 사본을 허용하지 않습니다. 추가 검사가 필요합니다.

이를 위해, 우리는 기준 선택 K = 10 , 즉 여기서 K > 10 ⋅ 합계 (A), 및 상기베이스의 어느 것도 체크되지 K 다음베이스로의 디지트 오버플 k 개의 열로 자리 때 곱셈 몫. 모든 즉 E 몫 회 10베이스 열 표현의 끝에서 시작 번째 염기 십 자리는, 상기 지수가 음이 아닌 요소 배열로 다시 변환하는 것이 0이 보장해야한다.


1
기본 변환을 쉽게하기 위해 10의 거듭 제곱을 기본으로 사용하는 트릭을 좋아합니다.
Neil

2

PHP, 213 바이트

같은 방식으로 약간 골프를 쳤다

<?for($b=2**~-$l=$_GET[1];$b<2**$l;array_filter($t[$b++])?:$d[]=$o)for($g=count($t[$b]=$_GET[$i=0]);min($t[$b])>-1&$i<=$g-$l;$i++)for($e=$t[$b][$i],$k=0,$o=decbin($b);$k<$l;)$t[$b][$k+$i]-=$o[$k++]*$e;print_r($d);

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

PHP, 344 바이트 첫 작업

첫 번째 답변을 마친 후 모든 유효한 솔루션을 다시 제공하기 위해 더 오래 시도하기로 결정했습니다.

<?foreach(range(2**($l=$_GET[1])-1,2**($l-1))as$b){$t[$b]=($g=$_GET[0]);for($i=0;$t[$b]&&$i<=count($g)-$l;$i++){$e=reset($y=array_slice($t[$b],$i,$l));foreach(str_split(decbin($b))as$k=>$v)$t[$b][$k+$i]=$y[$k]-$e*$v;if(min($t[$b])<0)unset($t[$b]);}}foreach($t as$k=>$v)if(max($v)>0)unset($t[$k]);echo join(",",array_map(decbin,array_keys($t)));

온라인 버전

고장

foreach(
    range(2**($l=$_GET[1])-1
    ,2**($l-1)
    ) # make decimal range of a binarray with given length
    as$b){
$t[$b]=($g=$_GET[0]); # make a copy for each possible solution pattern
    for($i=0;$t[$b]&&$i<=count($g)-$l;$i++){ # Loop till solution is valid or reach last digit
        $e=reset($y=array_slice($t[$b],$i,$l)); # take first value of a sequence with the length
        foreach(str_split(decbin($b))as$k=>$v)
            $t[$b][$k+$i]=$y[$k]-$e*$v; # replace values in copy
        if(min($t[$b])<0)unset($t[$b]); # kill solution if a minimum <0 exists
    }
}
foreach($t as$k=>$v)if(max($v)>0)unset($t[$k]); # drop all solutions where the sum is not zero 


echo join(",",array_map(decbin,array_keys($t))); #Output all solutions

이것은 N ≥ 2에서 작동하는 것처럼 보이지만 문제의 첫 번째 테스트 사례와 같은 N = 1 경우에는 실패합니다.
Anders Kaseorg 2012 년

@AndersKaseorg 이제 N = 1을 지원합니다 =. 짧은 버전의 첫 번째 루프 에서만 설정하면 됩니다. 큰 버전에서는 4 바이트를 삭제해야합니다.
Jörg Hülsermann

1

파이썬, 205 바이트

def f(a,l):
 b=lambda s:b(s[:-1])*sum(a)*8+int(s[-1])if s else 0
 c=lambda n:n and(n/sum(a)/4%2 or c(n/sum(a)/8))
 for i in range(2**~-l,2**l):
  j=bin(i)[2:]
  if b(a)%b(j)<1 and not c(b(a)/b(j)):return j

구분자가없는 이진 문자열을 반환합니다. @AndersKaseorg가 지적했듯이, 나눗셈이 허용되지 않는 음의 계수를 나타 내기 때문에 @ fəˈnɛtɪk의 솔루션이 작동하지 않는 입력이 있습니다. 이 문제를 해결하기 위해 매우 큰 기반을 사용하고 부서에 차입금이 없는지 테스트합니다.


: 좋아, 나는 이것이 실제 반례 생각 f([1, 1, 1, 0, 0, 0, 1, 1, 1], 3)이 잘못 돌아갑니다 101.
Anders Kaseorg 2016 년

@AndersKaseorg Hmm, 루프 순서를 바꾸는 것이 도움이됩니까, 아니면 알고리즘이 여전히 근본적으로 고장입니까?
Neil

추가 검사없이 근본적으로 고장 났다고 생각합니다. 역 변형은 실패 f([1, 0, 2, 0, 2, 0, 1], 3)하고 정방향 및 역 변형은 모두 실패합니다 f([1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0], 5).
Anders Kaseorg 2016 년

그리고 그것이 i홀수 인지 확인하더라도 정방향 및 역방향 변형은 모두 실패합니다 f([1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]*10, 5).
Anders Kaseorg 2016 년

1
@AndersKaseorg Ah 네, gcd (k, n) = 1 일 때, (x^kn-1)/(x^k-1)항상 (x^n-1)/(x-1)어떤 기반이든 @ fəˈnɛtɪk의 솔루션을 속이는 요소가 있습니다.
Neil

1

Pyth, 32 바이트

f!|%FKiRJysQ,QT>#sQj/FKJ+L1^U2tE

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

작동 원리

                           ^U2tE   Cartesian power [0, 1]^(N - 1)
                        +L1        prepend 1 to every list
f                                  filter for lists T such that:
          sQ                         sum(A)
         y                           double
        J                            assign to J
      iR    ,QT                      convert [A, T] from base J
     K                               assign to K
   %F                                fold modulo
  |                                  logical OR with
                    /FK                fold integer division over K
                   j   J               convert to base J
               >#sQ                    filter for digits greater than sum(A)
 !                                   logical NOT

Pyth에는 기본 변환을위한 기본 제공 기능이 있으므로 더 효율적인 기본 k = 2 ⋅ sum (A)를 사용하고 몫의 모든 숫자가 최대 합계인지 직접 확인할 수 있다는 점을 제외하면 이 전략은 Python 답변 과 유사합니다 . ).


1

Pari / GP , 77 74 96 80 바이트

n->a->[v|d<-divisors(b=Pol(a)),(v=Vec(d))%2==v&&vecmin(Vec(b/d))>=0&&d%x&&#d==n]

모든 솔루션을 반환합니다.

먼저 배열 a을 다항식으로 변환합니다 b. 그런 다음 제수 b에서 다항식을 선택 d하여 계수 d가 모두 10이고 계수 b / d가 모두 음이 아닌 및 d(0) = 1, 및을 선택 deg(d) = n + 1합니다. 마지막으로 다시 배열로 변환합니다.

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

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