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 टिप्पणी के लिए धन्यवाद। मैंने अभी मूल पोस्ट पर संपादित और विस्तृत किया है।
लार्स मैल्मस्टीन

जवाबों:


2

एक नंगे पैर समाधान

आइए एक अनुक्रम के एक जिस्ट को प्रिंट करने के लिए एक बहुत ही सरल समाधान के साथ शुरू करें। यह आपके द्वारा अपने प्रश्न में जोड़े गए विशेषकों से नहीं निपटता है लेकिन यह एक अच्छा प्रारंभिक बिंदु है:

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

इसके विपरीत .kv, जो अपने इनवोकेंट को फॉर्म में परिवर्तित करता है key1, value1, key2, value2, key3, value3, ..., यानी 6 तत्वों को अगर इसके इनवोकेंट में 3 तत्व हैं, तो .pairsअपने इनवोकेंट को फॉर्म में परिवर्तित करता है key1 => value1, key2 => value2, key3 => value3, ...

मैंने आंशिक रूप से .pairsइसके बजाय उपयोग किया .kvक्योंकि इसका मतलब था कि मैं ».gistबाद में कोड में बाद में आसानी से key1 => value1प्रत्येक तत्व के लिए एक अच्छा प्रदर्शन प्राप्त कर सकता था । हम इसे नीचे संशोधित करेंगे लेकिन यह एक अच्छी मुहावरेदार शुरुआत है।

.headऔर .tailकॉल मुहावरेदार तरह से एक invocant सूची से पहली और आखिरी एन तत्वों की छोटी सूची बनाने के लिए कर रहे हैं (बशर्ते वह आलसी नहीं है, के बारे में अधिक एक मो में)।

इस प्रारंभिक समाधान को देखते हुए, 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-gistउप अब कर रहे हैं .&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)

अगला, यह अच्छा होगा यदि उप कुछ उपयोगी है अगर एक सीमा या गिस्ट के बिना कहा जाता है। हम अधिकतर @rangeऔर &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)
}

न्यूनतम समाधान काफी ठीक काम करता है और यह शालीनता से मुहावरेदार भी है। मेरे समाधान में मुझे एक 'फ्लैग' वैरिएबल का सहारा लेना पड़ा था, ...क्योंकि यह एक सी प्रोग्राम की तरह लग रहा था। तो यह मेरे सवाल के दोनों हिस्सों का जवाब देता है, वास्तव में। 'व्यापक' समाधान के लिए, यह थोड़ा डराने वाला लगता है, वास्तव में।
लार्स मैल्मस्टीन

आपकी प्रतिक्रिया के लिए धन्यवाद और मेरे उत्तर को स्वीकार करने @LarsMalmsteen। उस ने कहा, मैंने अपने उत्तर को पूरी तरह से फिर से लिखा है और महसूस किया है कि यह बहुत बेहतर है। मैं 'व्यापक' समाधान गिरा दिया है - मैं उस के साथ मातम में दूर चला गया हूँ! - लेकिन मैंने पूरी तरह से "न्यूनतम समाधान" और साथ के स्पष्टीकरण को फिर से लिखा है। मैंने ज्यादातर बाद के पाठकों के लिए ऐसा किया, लेकिन आपको नए उत्तर को पढ़ने से कुछ मूल्य मिल सकता है।
23

7

आप पर पहले N मानों को छोड़ सकते हैं किसी भी Iterable या Sequenceके साथ skip:

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

यदि आप कोई संख्या निर्दिष्ट नहीं करते हैं, तो यह केवल एक तत्व को छोड़ देगा।


skip0 सूचकांक (a0) अवशेष के साथ सिर्फ ouput यानी तत्व दूर करने के लिए लगता है। मैंने कोशिश की है @seq:deleteऔर इसे 0 वें तत्व के साथ बदल दिया है(Any)
लार्स मैल्मस्टीन

वास्तव में। skipबस के रूप में अगर छोड़ दिया तत्वों मौजूद नहीं है में कार्य करेगा। यह आप क्या चाहते हैं या नहीं हो सकता है :-)
एलिजाबेथ मैटीजसेन

जब मैं इसे skipबीच में रखता हूं ताकि यह पढ़े: for @seq[^10].skip(0).kvयह सचमुच 0 तत्व को नहीं छोड़ता है और इससे कोई फर्क नहीं पड़ता कि मैं skip1 या 2 के तर्क के रूप में देता हूं , यह सिर्फ बाहर को विकृत करता है। ग्राउंड अप से 0 वें तत्व को निकालने के लिए मुझे एक व्यावहारिक तरीका चाहिए।
लार्स मैल्मस्टीन

1
शायद for @seq[^10].kv.skip(2)तुम क्या देख रहे हो?
एलिजाबेथ मैटीजसेन

हाँ जो काम करता है। वास्तव में मैं 2 के अलावा अन्य तर्क का उपयोग करने के skipबाद डालने की कोशिश की .kv, तो यह काम नहीं किया। समाधान के लिए धन्यवाद।
लार्स मैल्मस्टीन

7

यह थोड़ा अधिक मुहावरेदार हो सकता है:

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

आपको अनुक्रम के भीतर एक शाब्दिक चर का उपयोग करने की आवश्यकता नहीं है; या तो Whateverया प्लेसहोल्डर चर को सुरक्षित रूप से दृश्यों के भीतर इस्तेमाल किया जा सकता है। फिर आप बस उस अनुक्रम के तत्वों का चयन कर सकते हैं जिसे आप मुद्रित करना चाहते हैं। जो लौटता है«(0 1 2 3)(7 8 9 10)␤»


जवाब के लिए धन्यवाद। whateverऑपरेटर refreshening है लेकिन श्रृंखला / अनुक्रम उत्पादन मुख्य मुद्दे के समाधान नहीं करता है। मैं श्रृंखला को प्रिंट करना चाहता हूं, क्योंकि वे गणित टेक्सबुक पर देखे जाते हैं, अर्थात ...बीच में अंकन के साथ ।
लार्स मैल्मस्टीन

@LarsMalmsteen, ठीक है, मैं इसे संपादित करूँगा
jjmerelo
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.