주간 챌린지 #085 작업 #1::(Raku)
17166 단어 challengerakuperlweeklychallenge
작업 #1 › 삼중합
제출자: Mohammad S Anwar
0보다 큰 실수 배열이 제공됩니다.
1 < a+b+c < 2와 같은 삼중항(a,b,c)이 있는지 찾는 스크립트를 작성하세요. 성공하면 1을 출력하고 그렇지 않으면 0을 출력하세요.
Example 1:
Input: @R = (1.2, 0.4, 0.1, 2.5)
Output: 1 as 1 < 1a.2 + 0.4 + 0.1 < 2
Example 2:
Input: @R = (0.2, 1.5, 0.9, 1.1)
Output: 0
Example 3:
Input: @R = (0.5, 1.1, 0.3, 0.7)
Output: 1 as 1 < 0.5 + 1.1 + 0.3 < 2
부동 대 유리수
Raku에서는 부동 소수점 값을 저장하는 두 가지 유형이 있는 것 같습니다. 실제로 우리는 대부분의 부동 소수점을 다음과 같은 유리수로 표현할 수 있습니다.
1.7 -> 10 / 17
그리고 문서에는...
Since, unlike Rat, FatRat arithmetics do not fall back Num at some point, there is a risk that repeated arithmetic operations generate pathologically large numerators and denominators.
그래서 쥐가 이 작업에 충분하다고 생각합니다. 쥐를 만드는 것은 간단합니다. 숫자가 정수 값이더라도 점을 추가하십시오.
> (1.0).WHAT
(Rat)
> (1.7).numerator
17
> (1.7).denominator
10
> 1.Rat # or you can declare explicitly
간편한 샘플
그래서 우리는 유리수 3중항이 필요합니다. 다음 코드는 작업에 적합한 난수를 생성합니다.
> (10..99).pick(10).map({ (|(0 xx 10), |(0..3)).pick + $_/100 })
(3.24 0.75 0.83 0.74 0.58 0.85 1.68 0.81 0.59 0.12)
삼중항의 조합
제가 조합에 너무 집착하는 걸지도요 😂
> my @r = (10..99).pick(10).map({ (|(0 xx 10), |(0..3)).pick + $_/100 })
[0.23 0.1 0.13 0.56 0.81 0.71 1.4 0.79 0.16 0.52]
> @r.combinations(3).head(3) # head() can take an argment
((0.23 0.1 0.13) (0.23 0.1 0.56) (0.23 0.1 0.81))
삼중항의 합
우리가 원하는 값은 1과 2 사이입니다(또는 비교하기 쉽게 1.0과 2.0).
> @r.combinations(3).grep( -> \t { 1.0 < t.sum < 2.0 } );
((0.23 0.1 0.81) (0.23 0.1 0.71) (0.23 0.1 1.4) (0.23 0.1 0.79) ...
좋아요.. 그 결과가 너무 많습니다. 🤪
하나만 찾아서 💖
인간은 욕심이 너무 많습니다. 우리는 더 많은 것을 찾고 있고 우리가 필요한 것은 하나의 가능한 대답인데도 프로세서를 고통스럽게 만듭니다.
> @r.combinations(3).grep( -> \t { 1.0 < t.sum < 2.0 } ).head;
((0.23 0.1 0.81))
그리고 아마도 삼중항 자체만을 얻기 위해 평평해질 것입니다.
> @r.combinations(3).grep( -> \t { 1.0 < t.sum < 2.0 } ).head.flat;
(0.23 0.1 0.81)
잠깐만... 하지만 우리는 📔 first()
First()는 머리가 아닙니다.
단순히 head()를 first()로 바꾸면 ...
> @r.combinations(3).grep( -> \t { 1.0 < t.sum < 2.0 } ).first;
(0.23 0.1 0.81)
비슷하게 보일 수 있지만 flat()이 필요하지 않으며 first()는 객체를 검색하는 방법을 제공합니다.
> @r.combinations(3).first( -> \t { 1.0 < t.sum < 2.0 } );
좋은. 아마도 아래 코드와 비슷한 일을 할 것입니다.
> @r.combinations(3).grep( -> \t { 1.0 < t.sum < 2.0 } ).lazy.first;
grep()은 조합으로 만들어진 모든 경우를 원하고 모든 경우를 확인할 때까지 완료되지 않기 때문입니다. 그리고 더 나쁜 것은 파트너에게 나쁜 습관에 대해 한꺼번에 이야기하면 끝나기도 전에 떠날 것입니다. 그렇죠? 피곤하다는 뜻입니다.
그러나 .lazy()를 추가하면 값을 얻고자 할 때마다 평가됩니다.
나는 grep()을 호출하기 전에 조합()이 가능한 모든 조합을 얻으려고 시도하여 .lazy()를 조합()에 추가할 수 있다고 생각합니다. 목록이 짧더라도 전체 프로그램을 약간 느리게 만들 뿐이지 아프지 않으므로 추가했습니다.
최종 코드
#!/usr/bin/env raku
unit sub MAIN ( *@r where { @r.all ~~ Rat and @r.all > 0.0 } );
@r.
grep(* < 2.0).
sort.
combinations(3).
lazy.
first( 1.0 < *.sum < 2.0 )
andthen say("1.0 < "
~ "({join(' + ', $_.List)})"
~ " < 2.0")
orelse say "0";
위의 코드는 두 번째 솔루션이며 비교를 위해 첫 번째 솔루션을 남겨 둡니다. 더 라쿠틱해 보이길래 두 번째로 찍었습니다.
#!/usr/bin/env raku
unit sub MAIN ( *@a where { @a.all ~~ Rat and @a.all > 0 } );
my $triplet-it = @a.combinations(3).iterator;
my $found = False;
loop ( my $t := $triplet-it.pull-one;
($t =:= IterationEnd).not
; $t := $triplet-it.pull-one ) {
if 1.0 < $t.sum < 2.0 {
$found = True;
say("1.0 < "
~ "({join(' + ', $t.List)})"
~ " < 2.0");
last;
}
}
say 0 unless $found;
나쁘지 않다. 그렇지 않아? 명령형 또는 OOP 접근 방식일 가능성이 더 높아 보입니다.
알았어, 그게 다야
읽어 주셔서 감사합니다 !!
🐪PWC🦋에서 다른 도전을 확인하십시오
Reference
이 문제에 관하여(주간 챌린지 #085 작업 #1::(Raku)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/jeongoon/weekly-challenge-085-task-1-raku-4de3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)