범위를 수리


30

일부가로 바뀐 양의 정수 목록을 입력하면 0바뀐 숫자가 바뀐 목록을 0바꿉니다.

입력 목록의 특성 :

  • 목록의 길이는 항상 2 이상입니다.

  • 입력 목록을 a"원본 목록"(즉, 숫자가 0s 로 대체 된 목록 )으로 정의 b합니다. 어떤을 위해 n, a[n]중입니다 b[n]또는 0.

  • 어떤을 위해 n, b[n]중입니다 b[n-1] + 1또는 b[n-1] - 1. 즉,의 숫자 b는 항상 1이전 인덱스에서 각 인덱스마다 변경됩니다 . 물론 첫 번째 요소는이 규칙에서 제외됩니다.

  • 에서 제로의 모든 실행을 위해 a(교체, 연속적인 요소입니다 0함께) x실행의 시작의 인덱스를 나타내는과 y 끝을 대표 a[x-1]하는 a[y+1]항상 단독으로 감소 단독으로 증가 또는됩니다. 따라서 0을 채우는 가능한 방법은 하나뿐입니다.

    • 이것은 또한 배열의 첫 번째 요소와 마지막 요소가 모두 0이 될 수 없음을 의미합니다.

간단히 말해서, 0을 채우려면 간단히 그 숫자를 앞에있는 숫자에서 그 뒤에 나오는 숫자로 바꾸십시오. 예를 들어,

1 2 0 0 0 6 7

출력해야합니다

1 2 3 4 5 6 7

이것은 이므로 바이트 단위의 가장 짧은 코드가 승리합니다.

테스트 사례 :

In                      Out
-----------------------------------------------------
1 0 0 0 5 6 0 4 0 0 1 | 1 2 3 4 5 6 5 4 3 2 1
7 6 0 0 3 0 0 0 7 0 5 | 7 6 5 4 3 4 5 6 7 6 5
1 0 3 0 5 0 3 0 5 0 7 | 1 2 3 4 5 4 3 4 5 6 7
14 0 0 0 0 0 0 0 0 23 | 14 15 16 17 18 19 20 21 22 23

대신에 0우리의 프로그램은 다음과 같은 다른 가치를 가질 수 null있습니까?
Downgoat

@Downgoat 아니요, 누락 된 숫자는로 지정해야합니다 0.
Doorknob

답변:


15

자바 스크립트 (ES6), 72 66 64 54 53 바이트

@Neil 덕분에 12 바이트를 절약했습니다!

@IsmaelMiguel 덕분에 1 바이트 절약

a=>a.map((l,i)=>l?b=l:b+=a.find((q,r)=>r>i&&q)>b||-1)

JavaScript에 아주 좋습니다.


온라인으로 사용해보십시오 (모든 브라우저에서 작동)

설명

a=>  // Function with arg `a`
  a.map((l,i)=>  // Loop through input
    l?             // If nonzero
      b=l          // Set `b` to current number
    :a.find((q,r)=>r>i&q) // Otherwise look for the next nonzero number
     >b?           // If it's increased since nonzero last number   
       ++b:--b)    // Increasing? increase `b` (the previous nonzero number)
                   // otherwise decrease `b`

1
나는 그것이 a.find((q,r)=>r>i&&q)>b?++b:--b동일 하다고 생각합니다b+=a.find((q,r)=>r>i&&q)>b||-1
Ismael Miguel

@IsmaelMiguel 똑똑합니다, 감사합니다!
Downgoat

천만에요. 나는 그것이 당신을 위해 일하게되어 기쁘다.
Ismael Miguel

나는 당신이 단지 및 (그냥 당신이 대답 한 & 설명과 두가 발견)와 && 대체 할 수 있다고 생각
찰리 윈


7

하스켈, 68 61 58 바이트

g(a:b:r)=[a..b-1]++[a,a-1..b+1]++g(b:r)
g x=x
g.filter(>0)

사용 예 : g.filter(>0) $ [7,6,0,0,3,0,0,0,7,0,5]-> [7,6,5,4,3,4,5,6,7,6,5].

작동 방식 : 입력에서 0을 제거한 다음을 호출하십시오 g. 하자 a최초되고 b나머지리스트의 다음 번째 요소. 목록을 a위쪽 b-1에서 a아래쪽으로 b+1( 아래 중 하나는 비어 있음) 연결하고 재귀 호출은 a끊어 놓습니다.

편집 : @ Zgarb는 3 바이트를 저장했습니다. 감사!


6

수학, 59 바이트

#//.{a___,x_,0..,y_,b___}:>{a,##&@@Range[x,y,Sign[y-x]],b}&

테스트 사례

%[{1,0,3,0,5,0,3,0,5,0,7}]
(* {1,2,3,4,5,4,3,4,5,6,7} *)

4

펄, 47 45 44 39 37 바이트

에 +1 포함 -p

s%\S+%$p+=/\G(0 )+/?$'<=>$p:$&-$p%eg

stdin의 목록을 예상합니다. 예 : echo 1 0 3 0 1 | perl -p file.pl


여기에 붙여 넣기 사본이 보입니다 .. ;-) btw.
Kenney 2019

3

젤리, 12 11 바이트

ḢWW;ḟ0Ṫr¥\F

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

대체 버전, 8 바이트 (비경쟁)

불행히도, Jelly 's pop는이 문제를 선행하는 최신 버전에서 이터 러블에 캐스트하지 않았습니다. 이 문제는 해결되었으며 현재 버전에서 다음과 같이 작동합니다.

ḟ0Ṫr¥\FḊ

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

작동 원리

ḢWW;ḟ0Ṫr¥\F  Main link. Input: A (list)

Ḣ            Pop the first element of A. Let's call it a.
 WW          Yield [[a]].
   ;         Concatenate with the popped A.
             This wraps the first element of A in an array.
    ḟ0       Filter; remove all zeroes.
        ¥    Create a dyadic chain:
      Ṫ        Pop the last element of the left argument.
       r       Call range on the popped element and the right argument.
         \   Reduce the modified A by this chain.
          F  Flatten the resulting list of ranges.

대체 버전에서는 ḢWW;불필요하게됩니다. 그러나 첫 번째 요소는 터지기 전에 반복 가능으로 캐스팅되므로 실제로 수정되지는 않습니다. 마지막 은 첫 번째 요소의 복제본을 제거합니다.


3

망막, 39 34 31 바이트

@Martin 덕분에 3 바이트가 절약되었습니다.

+`1(1*) (?= +((1)\1)?)
$0$1$3$3

입력을 받아 단항으로 출력합니다.

이 코드는 모든 빈 자리 (0)를 반복적으로 채 웁니다 previous_number - 1 + 2 * if_next_nonzero_number_bigger. previous_number - 1이다 $1하고 if_next_nonzero_number_bigger있다 $3.

10 진 I / O를 사용하면 모든 테스트 케이스 가있는 온라인 인터프리터 에서 볼 수 있듯이 코드 길이는 51 바이트 입니다.


1미리보기 에서 첫 번째 바이트를 생략하여 다른 바이트를 저장할 수 있습니다 .
Martin Ender

@ MartinBüttner 맞습니다. 편집했습니다.
randomra

2

GNU Sed ( execbash를 사용한 확장), 61

-rsed 옵션에 대한 점수는 +1입니다 .

:
s/( 0)+ /../
s/\w+..\w+/{&}/
s/.*/bash -c 'echo &'/e
/ 0/b
  • 의 실행 찾기 0들과 그들을 대체..
  • 엔드 포인트 번호를 중괄호로 묶어 {1..4}로컬 엔드 포인트 처럼 괄호 확장을 만듭니다 . 여기서 bash 괄호 확장장점 은 생성 된 시퀀스가 ​​시작 또는 종료의 크기에 관계없이 항상 올바른 방향으로 실행된다는 것입니다.
  • 이 괄호 확장을 평가하기 위해 bash를 호출 e하려면 s명령에 대한 옵션을 사용하십시오.
  • 0s가 더 있으면 시작으로 돌아갑니다.

이데온


2

파이썬 2, 195 111 바이트 ( 알렉스 감사합니다 !)

t=input()
z=0
for i,e in enumerate(t):
 if e:
  while z:t[i-z]=e+z if l>e else e-z;z-=1
  l=e
 else:z+=1
print t

입력 : [list]정수 여야합니다.
출력 : [list]정수입니다.


미안합니다! 결정된. 고마워요
vageli

걱정 마. 좋은 해결책. :) this를 사용하여 112 바이트로 줄일 수 있습니다. 방법은 조금 더 골프입니다. 또한 파이썬 에서 골프를 치기위한 팁을 모아 놓았습니다 .
Alex A.

1

펄, 85 82 바이트

+1 포함 -p

s/(\d+)(( 0)+) (\d+)/$s=$1;$e=$4;$_=$2;$c=$s;s!0!$c+=$e<=>$s!eg;"$s$_ $e"/e&&redo

stdin의 목록을 예상합니다. 예 : echo 1 0 3 0 1 | perl -p file.pl.

이것은 중첩 정규 표현식을 사용합니다. 다소 읽기 쉬운 :

s/(\d+)(( 0)+) (\d+)                  # match number, sequence of 0, number
 /
    $s=$1;                            # start number
    $e=$4;                            # end number
    $_=$2;                            # sequence of ' 0'
    $c=$s;                            # initialize counter with start number
    s!0! $c += $s <=> $e !eg          # replace all 0 with (in|de)cremented counter
    "$s$_ $e"                         # return replacement
 /e
&& redo                               # repeat until no more changes.

1

파이썬 2, 92 88 바이트

(중간 변수 제거)

t=filter(bool,input())
print sum([range(o,p,cmp(p,o))for o,p in zip(t,t[1:])],[])+t[-1:]

1

Pyth, 17 바이트

u+G+treGHHfTtQ[hQ

작동 방식 :

u                 reduce
              [hQ     seed: the first element of input, in a list
                      iterable:
          tQ              all except the first element of input
        fT                remove if 0
                      lambda: G is the list to be returned, H is the current item
 +G                       append to return list
    reGH                  a range from the last element of the return list and the current item
   +                      concatenated with
        H                 the last item (this step forms a bidirectional inclusive list)

즉, 모든 0이 입력에서 제거 된 후 모든 요소 사이에 배타적 범위가 삽입됩니다. 이 범위는 길이가 0 인 요소의 길이는 0입니다.



1

Vim : 231 키 명령

문자 앞에있는 ^는 해당 문자를 입력하는 동안 제어 권한을 보유해야 함을 의미합니다.

mbomayiwo^V^R"^V^V^V^X ^V^["sy0dd`a@f ^["bc0yiwo^V^V^V^X^V^R"^V^[0l@sa^V^V^V^A-^V^[0f-"ayhdd`a@i ^["dc0mbyiwo^V^R"Exe@b^V^[0fel"ty2ldd`b@t ^["ec0wmbyiwo@f @d^V^[@z ^["fc0"xyiwwmbyiwocw^V^V^V^Rx^V^V^V^[@a@i @e^V^[@z ^["ic0IB0 B^V^R" ^V^OWB0 ^V^OA B0^V^[0*w"tyiWdd`b@t ^["zd0dd`bAe^[0@e 

당신도 이것을 실행할 수 있도록 단계!

  1. Vim에 줄을 복사
  2. 입력 :s/\^V/<Ctrl-V><Ctrl-V>/g하고 Enter 키를 누릅니다 (두 s에 파란색 ^ V가 표시되어야 함)
  3. 입력 :s/\^R/<Ctrl-V><Ctrl-R>/g하고 Enter 키를 누릅니다 (이제 파란색 ^ R이 표시됩니다)
  4. 입력 :s/\^X/<Ctrl-V><Ctrl-X>/g하고 Enter 키를 누릅니다 (지금 파란색 ^ X가 표시됨)
  5. 입력 :s/\^O/<Ctrl-V><Ctrl-O>/g하고 Enter를 누르십시오
  6. 입력 :s/\^A/<Ctrl-V><Ctrl-A>/g하고 Enter를 누르십시오
  7. 입력 :s/\^\[/<Ctrl-V><Ctrl-[>/g하고 Enter 키를 누릅니다 ([
  8. 을 입력하십시오 0"yy$. 명령은 이제 y 레지스터에 저장됩니다
  9. 라인에 입력을 설정하고 @y

누군가가 명령을 공유하는 더 좋은 방법을 알고 있다면 알려주십시오. 나는 이것이 길다는 것을 알고 있지만, 내가 생각해 낼 수있는 최선입니다.

입출력

입력 문자열은 파일의 모든 행에서 단독이어야합니다. 1000 34 0 0 7

출력은 단순히 입력 문자열을 덮어 씁니다. 1 2 3 4 3 4 5 6 7

설명

연산

  1. 0이 아닌 숫자로 시작하여 마지막 숫자가 아닌지 확인하십시오.
  2. 0이 아닌 다음 숫자 찾기
  3. 그들의 차이를 가져 가라. 대답이 음수이면 범위를 수리하기 위해 감소해야하며, 그렇지 않으면 범위를 수리하기 위해 증가해야합니다.
  4. 첫 번째 문자로 돌아가서 이전 숫자를 증가 / 감소시켜 각각의 0을 대체하십시오.
  5. 마지막 캐릭터가 나올 때까지 반복

사용 된 매크로

@e-종료를 확인하십시오. 마지막 숫자에는 e가 붙습니다. 커서 아래의 숫자에 끝에 e가 있으면 e를 삭제하고 실행을 중지하십시오. 그렇지 않으면 @b를 사용하여 보간 사이클을 시작하십시오.

mbyiwo^R"Exe@b^[0fel"ty2ldd`b@t

@b-보간 사이클을 시작합니다. 빼기 연산 (@s)을 위해 커서 아래에 숫자를 저장하고 0이 아닌 다음 항 (@f)을 찾으십시오.

mayiwo^R"^V^X ^["sy0dd`a@f

@s-@d에서 사용할 빼기 명령을 저장합니다. 보간 단계 시작 부분의 숫자 는 단순히 (val)^X어디에 (val)있습니다. 이것은 @b 명령에 의해 설정됩니다.

@f-0이 아닌 다음 항을 찾습니다. 현재 값을 명명되지 않은 레지스터에 쓴 @f @d다음 다음 줄에 쓰고 @z를 실행합니다. 숫자가 0이면이 명령을 반복하고 그렇지 않으면 @d를 실행합니다.

wmbyiwo@f @d^[@z

@z-명명되지 않은 레지스터가 0 인 경우 조건부 실행.이 명령은 새 행에 두 개의 명령 형식이 필요합니다 command1 command2. 명명되지 않은 레지스터가 0이면 command1실행되고 그렇지 않으면 command2실행됩니다. 어떤 명령도 공백을 가질 수 없습니다.

 IB0 B^R" ^OWB0 ^OA B0^[0*w"tyiWdd`b@t`

@t-임시 명령 레지스터. 다양한 명령을 실행하기 전에 짧은 시간 동안 저장합니다. if 문에서 주로 사용됩니다.

@d-보간 방향을 결정합니다. 커서 아래의 숫자에서 시퀀스의 첫 번째 숫자를 뺍니다 (@s 사용). 결과가 음수이면 보간을 줄여야 ^ X가 @a에 저장됩니다. 그렇지 않으면 ^ A가 @a에 저장되도록 증가시켜야합니다. 이것이 저장되면이 보간 사이클의 시작으로 돌아가서 실제로 보간하기 위해 @i를 실행하십시오

yiwo^V^X^R"^[0l@sa^V^A-^[0f-"ayhdd`a@i

@a - 상점 중 하나 ^A또는 ^X보간 단계에서 증가 또는 감소합니다. 이것은 @d 명령에 의해 설정됩니다.

@i-보간. 현재 위치의 번호를 @x에 복사하고 다음 번호로 이동하십시오. 해당 숫자가 0이면 @x로 바꾸고 @a를 실행하여 위 또는 아래로 올바르게 수정 한 다음이 명령을 반복하십시오. 숫자가 0이 아닌 경우이 보간주기의 끝에 도달 한 것입니다. 이 번호로 시작하는 새로운 번호를 시작해야하므로 @e를 실행하여 끝을 확인한 후 다시 실행하십시오.

"xyiwwmbyiwocw^V^Rx^V^[@a@i @e^[@z

@x-임시 저장 레지스터. 보간 명령에 사용됨 (@i)

키 입력 세분화

mbo :Set b mark to current position and open a new line below to write macros
mayiwo^V^R"^V^V^V^X ^V^["sy0dd`a@f ^["bc0 :Write to @b and reset line

yiwo^V^V^V^X^V^R"^V^[0l@sa^V^V^V^A-^V^[0f-"ayhdd`a@i ^["dc0 :Write to @d and reset line

mbyiwo^V^R"Exe@b^V^[0fel"ty2ldd`b@t ^["ec0 :Write to @e and reset line

wmbyiwo@f @d^V^[@z ^["fc0 :Write to @f and reset line

"xyiwwmbyiwocw^V^V^V^Rx^V^V^V^[@a@i @e^V^[@z ^["ic0 :Write to @i and reset line

IB0 B^V^R" ^V^OWB0 ^V^OA B0^V^[0*w"tyiWdd`b@t ^["zd0 :Write to @z and reset line

dd`b :Delete this line and move cursor back to original line

Ae^[ :Append an e to the last number

0@e  :Move to the beginning of the line and run

0

Python 3.5, 159 바이트

재귀 솔루션

def f(s):
 h=s[0]
 g=lambda s,h,v:h*(h[-1]==s[0])if len(s)==1else(g(s[1:],h+[h[-1]-v],-v)+g(s[1:],h+[h[-1]+v],+v))*(s[0]==0 or h[-1]==s[0])
 return g(s,[h],1)

언 골프

def f(s):
    h=s[0]
    def g(s,h,v):
        if len(s)==1:
            if h[-1]!=s[0]:
                r=[]
            else:
                r=h
        else:
            if s[0]==0:
                r=g(s[1:],h+[h[-1]+v],v)
            elif h[-1]!=s[0]:
                r=[]
            else:
                r=g(s[1:],h+[h[-1]-v],-v)+g(s[1:],h+[h[-1]+v],+v)
        return r
return g(s,[h],1)

golfed 솔루션, 나는이 사실을 사용하여 조건을 대체 그 h*True=hh*False=[]

결과

>>> f([7, 6, 0, 0, 3, 0, 0, 0, 7, 0, 5])
[7, 6, 5, 4, 3, 4, 5, 6, 7, 6, 5]

0

펄 6 , 54 바이트

{$_=$^a;1 while s/:s(\d+) 0 + (\d+)/{+~$0...+~$1}/;$_}

0

MATLAB, 39 38 37 바이트

@(a)interp1(find(a),a(a>0),find(a/0))

의 점 사이를 선형으로 보간하는 익명 함수입니다 a. find(a)비 영 요소 인덱스의 배열 aa(a>0)양의 값이다. 친구가 >아닌 의 제안으로 1 바이트를 절약했습니다 ~=.

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