Raku에서 수학 시리즈를 간결하게 인쇄


9

수학 시리즈, 예를 들어 배열로 표시된 연속 시퀀스를 예로 들어 보겠습니다.

my @seq = my $a=0, {++$a} ... *;
for @seq[^10].kv {state $f=0; ($^k < 4 or $^k > 7) ?? say "a$^k =  "  ~ $^v !! (say "..." if $f ne 1; $f=1) };

인쇄물:

a0 =  0
a1 =  1
a2 =  2
...

a8 =  8
a9 =  9

내 질문 : 1- 첫 번째 요소, 즉 a0 = 0인쇄 된 출력에서 삭제하는 간단한 방법이 있습니까?

2-이 코드를 더 관용적으로 만들 수 있습니까?

감사합니다.


@DanBron 의견 감사합니다. 방금 원본 게시물을 편집하고 자세히 설명했습니다.
Lars Malmsteen

답변:


2

베어 본 솔루션

시퀀스의 요점을 인쇄하는 매우 간단한 솔루션부터 시작하겠습니다. 질문에 추가 한 세부 사항은 다루지 않지만 좋은 출발점입니다.

sub seq-range-gist ( @seq ) {
  my @pairs = @seq.pairs;
  join "\n", @pairs.head(3)».gist, '...', @pairs.tail(2)».gist
}

.kv그것의 invocant를 형태로 변환하는 것과 달리 , key1, value1, key2, value2, key3, value3, ...즉 그것의 invocant가 3 개의 요소를 포함하면 6 개의 element .pairs는 그것의 invocant를 형태로 변환한다 key1 => value1, key2 => value2, key3 => value3, ....

내가 사용하는 .pairs대신 .kv그것을 그냥 사용할 수있는 것을 의미 부분적으로 있기 때문에 ».gist쉽게 편안한를 얻을 수있는 코드에서 나중에 key1 => value1각 요소에 대한 표시. 우리는 아래에서 그것을 수정하지만 이것은 좋은 관용적 시작입니다.

.head.tail통화가 invocant 목록에서 첫 번째와 마지막 N 요소의 작은 목록을 만들 수있는 관용적 인 방법입니다 (이것은 게으른 아니다 제공, 더 그것에 대해 미주리).

이 초기 솔루션이 제공되면 다음을 say seq-range-gist (0,1 ... Inf)[^10]표시합니다.

0 => 0
1 => 1
2 => 2
...
8 => 8
9 => 9

다음으로, "인쇄 된 출력에서 ​​첫 번째 요소 만 삭제"할 수 있기를 원합니다. 불행히도 다음을 say seq-range-gist (0,1 ... Inf)[1..9]표시합니다 :

0 => 1
1 => 2
2 => 3
...
7 => 8
8 => 9

왼쪽의 =>숫자가 원래 순서의 번호를 유지하기를 원합니다 . 이를 가능하게하기 위해 추출하고자하는 범위에서 기본 시퀀스를 분리합니다. 두 번째 매개 변수 / 인수 @range를 추가 [@range]하고 하위의 두 번째 줄에 추가 합니다.

sub seq-range-gist ( @seq, @range ) {
  my @pairs = @seq.pairs[@range];

이제 우리는 say seq-range-gist (0,1 ... Inf), 1..9디스플레이에 쓸 수 있습니다 :

1 => 1
2 => 2
3 => 3
...
8 => 8
9 => 9

귀하의 질문에 당신은 aINDEX = VALUE대신 형식을 사용했습니다 INDEX => VALUE. 요점을 사용자 정의 할 수 있도록 세 번째 &gist루틴 매개 변수 / 인수를 추가 하고 내장 .gist메소드 대신 호출하십시오 .

sub seq-range-gist ( @seq, @range, :&gist ) {
  my @pairs = @seq.pairs[@range];
  join "\n", @pairs.head(3)».&gist, '...', @pairs.tail(2)».&gist
}

seq-range-gistsub 본문에서 "메소드"호출 이 지금 .&gist은 아니고 어떻게 작동하는지 주목하십시오 .gist. 구문 .&foo서브 &foo ( foo왼쪽의 호출자를 서브 .$_인수로 전달)를 전달 하는 서브 (일반적으로 그냥 작성하여 호출)를 호출합니다 .

또한 &gist매개 변수 앞에을 붙여 이름을 지정한 매개 변수를 만들었습니다 :.

이제 다음이 say seq-range-gist (0,1 ... Inf), 1..9, gist => { "a{.key} = {.value}" }표시됩니다.

a1 =  1
a2 =  2
a3 =  3
...
a8 =  8
a9 =  9

광택 추가

이 답변의 나머지 부분은 광택에 관심이있는 독자에게 보너스 자료입니다.

say seq-range-gist (0, 1, 2, 3), ^3 표시합니다 :

0 => 0
1 => 1
2 => 2
...
1 => 1
2 => 2

죄송합니다. 머리와 꼬리가 결합 된 것보다 더 많은 쌍이 있었더라도 적어도 반복 된 선을 얻지 못했지만 head, ..., tail한두 가지 요소 만 제거 하는 방법을 사용하면 여전히 의미가 없습니다 . 이러한 문제를 해결하기 위해 하위 본문의 마지막 문장을 변경해 보겠습니다.

  join "\n",
    @pairs < $head + $tail + 3   # Of course, the 3 is a bit arbitrary
      ?? @pairs».&gist
      !! (@pairs.head($head)».&gist, '...', @pairs.tail($tail)».&gist)

다음으로, 범위 나 요지없이 호출하면 서브가 유용한 것을 수행하면 좋을 것입니다. 우리는 주로 @rangeand &gist매개 변수에 적절한 기본값 을 지정하여 문제를 해결할 수 있습니다 .

sub seq-range-gist (
  @seq,
  @range = @seq.is-lazy ?? ^100 !! ^@seq,
  :&gist = { .gist }
) {

경우 @seq입니다 하지 게으른 다음 @range의 전체 범위 기본값 @seq. 경우 @seq입니다 무한 (이 경우 그것은 또한 게으른), 다음 100 개까지 기본 괜찮습니다. 그러나 @seq게으르지 만 정의 된 값이 100보다 작은 경우 어떻게됩니까? 이 경우를 다루기 .grep: *.value.defined위해 @pairs선언에 추가 합니다 .

  my @pairs = @seq.pairs[@range].grep: *.value.defined;

또 다른 간단한 개선 사항은 선택적인 헤드 및 테일 매개 변수이며 최종 광택 솔루션으로 이어집니다.

sub seq-range-gist (
  @seq,
  @range = @seq.is-lazy ?? ^100 !! ^@seq,
  :$head = 3,
  :$tail = 2,
  :&gist = { .gist }
) {
  my @pairs = @seq.pairs[@range].grep: *.value.defined;
  join "\n",
    @pairs <= $head + $tail + 2
      ?? @pairs».&gist
      !! (@pairs.head($head)».&gist, '...', @pairs.tail($tail)».&gist)
}

최소한의 솔루션은 꽤 잘 작동하며 또한 관용적입니다. 내 솔루션에서 나는 '플래그'변수에 의존 ...하여 C 프로그램처럼 보이게 하는 부분 을 생각 해야했습니다. 그래서 이것은 내 질문의 두 부분에 실제로 대답합니다. '포괄적 인'솔루션에 관해서는 실제로 약간 협박 적으로 보입니다.
Lars Malmsteen

의견을 보내 주셔서 감사합니다. @LarsMalmsteen 답변을 받아주십시오. 즉, 나는 내 대답을 완전히 다시 작성했으며 훨씬 나아졌습니다. 나는 '포괄적 인'솔루션을 떨어 뜨 렸습니다. 나는 잡초로 멀리 떨어졌습니다! -그러나 "최소 솔루션"과 함께 설명을 완전히 다시 작성했습니다. 나는 대부분의 다른 독자들을 위해 그렇게했지만 새로운 답변을 읽음으로써 가치를 얻을 수 있습니다.
raiph

7

다음 Iterable 하나를 Sequence사용 하여 첫 번째 N 값을 건너 뛸 수 있습니다 skip.

for (^5).skip(3) {
    .say
}
# 3
# 4

숫자를 지정하지 않으면 하나의 요소 만 건너 뜁니다.


skip출력을 제거 하는 것처럼 보입니다. 즉 0 번째 인덱스 (a0)를 가진 요소가 남아 있습니다. 나는 해봤 @seq:delete그리고 그것은 단지와 0 번째 요소를 교체(Any)
라스 Malmsteen

과연. 은 skip생략 요소가 존재하지 않는 것처럼 단지 역할을합니다. 이것은 당신이 원하는 것일 수도 아닐 수도 있습니다 :-)
Elizabeth Mattijsen

나는 넣으면 skip그래서 읽는 사이에 : for @seq[^10].skip(0).kv그것은 말 그대로 0 번째 요소를 생략하지 않으며, 그것은 중요하지 내가의 인수로 주면 않는 skip1 또는 2, 그냥 더 나아가를 왜곡. 0 번째 요소를 처음부터 제거하는 실용적인 방법이 필요합니다.
Lars Malmsteen

1
아마도 for @seq[^10].kv.skip(2)당신이 찾고있는 것입니까?
엘리자베스 마티 센 19

그렇습니다. 실제로 나는 skip후를 넣었 .kv지만 2 이외의 인수를 사용 하려고 시도했지만 작동하지 않았습니다. 솔루션 주셔서 감사합니다.
Lars Malmsteen

7

이것은 좀 더 관용적 일 수 있습니다.

my @seq = 0, *+1 ... *;
say @seq[^4], @seq[7..10]

시퀀스 내에서 어휘 변수를 사용할 필요는 없습니다. 하나 Whatever또는 자리 변수 안전하게 서열 내에서 사용될 수있다. 그런 다음 인쇄하려는 순서의 요소를 간단히 선택할 수 있습니다. 어떤 반환«(0 1 2 3)(7 8 9 10)␤»


응답 해주셔서 감사합니다. whatever연산자 재생기되지만 직렬 / 시퀀스 출력은 주요 문제를 해결하지 않는다. 수학 텍북에서 볼 수있는대로 (즉, ...사이에 표기된) 시리즈를 인쇄하고 싶습니다 .
Lars Malmsteen

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