주간 챌린지 #080 태스크 #1::라쿠

자~ 또 하나 Weekly Challenge #080

작업 #1 가장 작은 양수 비트



제출자: Mohammad S Anwar

정렬되지 않은 정수 목록 @N이 제공됩니다.

누락된 가장 작은 양수를 찾는 스크립트를 작성하십시오.
예 1:

Input: @N = (5, 2, -2, 0)
Output: 1

Example 2:

Input: @N = (1, 8, -1)
Output: 2

Example 3:

Input: @N = (2, 0, -1)
Output: 1

저는 골프 스타일의 프로그래머는 아니지만 Perl과 Raku는 골프 프로그래밍에 아주 좋은 프로그래머입니다.
(프로그래밍의 골프는 코드가 작업 요청을 출력하는 경우 효율적일 필요가 없는 길이로 가능한 짧게 작성됩니다. )
작업 #1의 뭔가 골치 아픈 가장자리를 느꼈고, 나는 Raku 을(를) 시도하고 싶었습니다.

입력을 받는 몇 가지 방법이 있습니다. STDIN의 입력은 사용자 데이터를 가져오는 일반적인 방법이지만 Perl Weekly Challenge는 데이터를 가져오는 방법에 대해 엄격하지 않습니다.

그래서 명령줄의 인수에서 정수 목록을 가져오기로 결정했습니다. 그리고 "MAIN"이라는 이름의 함수를 작성하면 서브루틴이 인수 목록을 매우 잘 처리합니다. 이것은 Raku가 꽤 좋은 클래스 시스템을 제공하고 인수에 대한 유형 확인이 매우 쉽고 사용자가 작업 자체에 집중할 수 있기 때문에 Raku가 빛나는 곳입니다.

 sub MAIN( *@args where @args.all ~~ Int ) {                                       
     @args.elems.say;                                                              
     @args.List.say;                                                               
 }             



raku test.raku 5 2 -2 0 # example #1
4
(5 2 -2 0)

인수에 문자열 값을 제공하면 친절하게 사용법을 알려줍니다. 단순한. 멋진. 하지만 기다려! 이 골프에서는 인수에 대한 세부 정보를 확인하지 않고 사용자 입력을 신뢰합시다. 그리고 자동으로 배열 형식의 일련의 값을 갖는 고대 변수 @_를 사용할 것입니다.

sub MAIN {  @_.say; }



raku test.raku 5 2 -2 0 # example #1
[5 2 -2 0]

(5 2 -2 0)과 [5 2 -2 0]의 차이를 알 수 있을까요?
전자는 List 후자는 Array입니다. 좋아요....
List(또는 Array)에서 값을 읽기만 하면 되기 때문에 이 작업에서는 별로 중요하지 않습니다.

가장 먼저 생각해야 할 것은 목록을 정렬하는 방법입니다.

sub MAIN { @_.sort.say; }

쉬운. then.. 우리는 두 개의 인접한 숫자를 비교해야 할 수도 있습니다
그리고 그들 사이의 차이가 1보다 큰 경우.
Raku에는 "rotor"이라는 훌륭한 내장 기능이 있습니다.

sub MAIN { @_.sort.rotor(2=>-1).say }
((-2 0) (0 2) (2 5))

아... 하지만 음의 정수 값은 필요하지 않습니다...
(BTW 제로는 괜찮습니다..)

sub MAIN { @_.sort.grep(*>=0).rotor(2=>-1).say }



((0 2) (2 5))

오키. 비교는 단순 빼기를 사용하여 수행됩니다.

sub MAIN {
    @_.sort.
       rotor( 2=>-1 ).
       map( -> ($a, $b) { $b - $a } ).
       say;
}



(2 3)

하지만 "3 4 5"가 있으면 어떻게 될까요?
그래서 목록(또는 배열)에 "0"을 추가해야 했습니다... 그리고 1 2 3이 있고 4를 찾아야 한다면 어떻게 될까요?
Raku는 가상 무한 값에 대해 Inf를 지원하므로 저도 추가합니다.
그리고 아마도 우리는 그들에게 고유한 루틴이 필요할까요?

sub MAIN {
    (|@_>>.Int,0,Inf).sort. # note "|" at the front of @_ will flatten the list. 
    unique.
    grep( * >= 0 ).
    rotor( 2 => -1 ).
    map( -> ($a, $b) { a => $b-$a } ).say;
}



(0 => 2 2 => 3 5 => Inf)

참고: @_는 실제로 Int가 아니라 IntStr을 취하므로 >>.Int를 추가해야 했습니다.

좋아.. 이제 차이가 1보다 큰 첫 번째 경우를 찾습니다. 즉 (0 => 2)
그리고 우리는 왼쪽 값을 알고 "1"을 추가하기만 하면 됩니다.
따라서 예제 #1의 결과는 "1"입니다.

최종 솔루션 형식은 위에서 작성한 것과 다릅니다.
하지만 그대로 떠나기로 했다. 누군가에게는 신기하고 재미있을 것 같아요.

그리고 기억하세요... 이것은 골프입니다. 항상 더 짧은 길이 있습니다.

sub MAIN{say((|@_,0,Inf).sort.rotor(2=>-1).first({.[0]>-1>[-] $_})[0]+1)}

좋은 웹페이지 즐겨찾기