তালিকার রাকুতে সমান উপাদানের সংলগ্ন ক্রমগুলি সন্ধান করা


9

আমি একটি তালিকায় সমান উপাদানের সংলগ্ন ক্রমগুলি (যেমন দৈর্ঘ্য 2) সন্ধান করতে চাই

my @s = <1 1 0 2 0 2 1 2 2 2 4 4 3 3>;
say grep {$^a eq $^b}, @s;

# ==> ((1 1) (2 2) (4 4) (3 3))

এই কোডটি ঠিক আছে বলে মনে হচ্ছে তবে যখন ক্রমের পরে আরও একটি 2 যুক্ত করা হয় 2 2 2বা যখন একটি 2 এর থেকে সরিয়ে ফেলা হয় তখন এটি বলে যে এটি Too few positionals passed; expected 2 arguments but got 1কিভাবে ঠিক করবেন? দয়া করে নোট করুন যে আমি forলুপ ব্যবহার না করেই তাদের সন্ধানের চেষ্টা করছি, আমি যথাসম্ভব একটি কার্যকরী কোড ব্যবহার করে তাদের সন্ধান করার চেষ্টা করছি।

Ptionচ্ছিক: সাহসী মুদ্রিত বিভাগে:

<1 1 0 2 0 2 1 2 2 2 4 4 3 3>

একাধিক ক্রম 2 2দেখা হয়। কীভাবে তাদের দেখা যায় তার সংখ্যা মুদ্রণ করবেন কীভাবে? ভালো লেগেছে:

((1 1) (2 2) (2 2) (4 4) (3 3))

উত্তর:


9

আপনার ইনপুটটিতে এমন অনেকগুলি উপাদান রয়েছে:

say elems <1 1 0 2 0 2 1 2 2 2 4 4 3 3>; # 14

আপনার grepব্লক প্রতিবার দুটি উপাদান গ্রাস করে:

{$^a eq $^b}

সুতরাং আপনি যদি কোনও উপাদান যুক্ত বা সরিয়ে ফেলেন তবে আপনি শেষে থাকা একক উপাদানটিতে ব্লকটি চালানোর সময় আপনি যে ত্রুটিটি পেয়ে যাবেন তা পেয়ে যাবেন।


আপনার সমস্যা সমাধানের বিভিন্ন উপায় রয়েছে are

তবে আপনি ওভারল্যাপিংয়ের অনুমতি দেওয়ার বিকল্প সম্পর্কেও জিজ্ঞাসা করেছিলেন, উদাহরণস্বরূপ, (2 2)ক্রমটি যখন আসে তখন আপনি দুটি উপ-তালিকা পাবেন 2 2 2। এবং, অনুরূপ শিরাতে, আপনি সম্ভবত দুটি ইনকয়ের মতো শূন্য নয়, ম্যাচ দেখতে চান:

<1 2 2 3 3 4>

সুতরাং আমি সেই সমস্যাগুলিকেও সমাধান করে এমন সমাধানগুলিতে মনোযোগ দেব।

অতিরিক্ত সমস্যাগুলি মোকাবেলা করার জন্য সমাধানের স্থান সংকীর্ণ হওয়া সত্ত্বেও, কার্যক্ষমভাবে সমাধান প্রকাশের অনেক উপায় রয়েছে।


একটি উপায় যা আপনার শেষের দিকে কিছুটা আরও কোড যুক্ত করে:

my @s = <1 1 0 2 0 2 1 2 2 2 4 4 3 3>;
say grep {$^a eq $^b}, @s .rotor( 2 => -1 ) .flat

.rotorপদ্ধতি উপ-তালিকা, একই দৈর্ঘ্য প্রতিটি একটি তালিকা মধ্যে একটি তালিকা পরিবর্তন করে। উদাহরণস্বরূপ, say <1 2 3 4> .rotor: 2প্রদর্শন করে ((1 2) (3 4))। যদি দৈর্ঘ্যের আর্গুমেন্টটি একটি জোড়া হয়, তবে কীটি দৈর্ঘ্য এবং মানটি পরবর্তী জোড়টি শুরু করার জন্য অফসেট। যদি অফসেটটি নেতিবাচক হয় তবে আপনি উপ-তালিকা ওভারল্যাপ পাবেন। এইভাবে say <1 2 3 4> .rotor: 2 => -1প্রদর্শিত হয় ((1 2) (2 3) (3 4))

.flatপদ্ধতি "চ্যাপ্টা" তার invocant। উদাহরণস্বরূপ, say ((1,2),(2,3),(3,4)) .flatপ্রদর্শন করে (1 2 2 3 3 4)

উপরের সমাধানটি লেখার সম্ভবত আরও পঠনযোগ্য উপায় হ'ল flatব্যবহার বাদ দেওয়া এবং ব্যবহার .[0]এবং .[1]ফিরে আসা সাব-তালিকাগুলি অনুসারে সূচি পাঠানো rotor:

say @s .rotor( 2 => -1 ) .grep: { .[0] eq .[1] }

যে কোনও উপ-তালিকা আকারের জন্য জেনারেলাইজ করে এমন অন্য পরিবর্তনের জন্য এলিজাবেথ ম্যাটিজসেনের মন্তব্যও দেখুন।


আপনার যদি আরও সাধারণ কোডিং প্যাটার্নের প্রয়োজন হয় তবে আপনি এমন কিছু লিখতে পারেন:

say @s .pairs .map: { .value xx 2 if .key < @s - 1 and [eq] @s[.key,.key+1] }

.pairsতালিকায় পদ্ধতি প্রতিটি জোড়া তার invocant তালিকায় উপাদানের প্রতিটি সংশ্লিষ্ট জোড়া একটি তালিকা প্রদান করে। .keyপ্রতিটি জোড়া এর invocant তালিকায় উপাদান সূচক হয়; .valueউপাদান মান।

.value xx 2লেখা যেতে পারে .value, .value। (দেখুন xx।)

@s - 1@sবিয়োগ 1 এ উপাদানগুলির সংখ্যা ।

[eq]মধ্যে [eq] listএকটি হল হ্রাস


আপনার যদি ইনপুট তালিকাটিকে স্ট্রিংয়ে রূপান্তর করতে পারে তার জন্য উপযুক্ত পাঠ্য প্যাটার্ন ম্যাচিংয়ের প্রয়োজন হয় তবে ম্যাচের একটি অ্যাডওয়্যার ব্যবহার করে ম্যাচের একটি তালিকা তৈরি করে তার সাথে মেলে, তারপরে ম্যাচের ফলাফলের তালিকা থেকে আপনার পছন্দসই ম্যাপ করুন ফলাফল. ওভারল্যাপের সাথে মেলে (যেমন ব্যবহারের 2 2 2ফলাফল :((2 2) (2 2)):ov

say @s .Str .match( / (.) ' ' $0 /, :ov ) .map: { .[0].Str xx 2 }

এটি বেশ সূক্ষ্ম কাজ করে। আমি যখন সিকোয়েন্স তৈরি করতে 2 2 টি যুক্ত করি তখন 2 2 2 2এটি 3 (2 2)টি প্রিন্ট করে যা প্রত্যাশিত। rotorআমি প্রথমে প্রথমে যে squishপদ্ধতিটি নিয়ে এসেছি সে সম্পর্কে কখনও শুনিনি এবং এটির বৈশিষ্ট্য বা আর্গুমেন্ট রয়েছে কিনা তা যাচাই করা হয়েছে @s.squish(:length 2, :multiple_instances yes)তবে এর বৈশিষ্ট্যগুলি নেই এবং এটি কাজের উপযুক্ত নয়। সঙ্গে তুলনা করা squish, rotor বেশ ফিট বলে মনে হচ্ছে। আসলে এটি এই ধরণের অপারেশনের জন্য উপযুক্ততমও হতে পারে।
লার্স মলমসটিন

3
my $size = 2; say <1 1 0 2 0 2 1 2 2 2 4 4 3 3>.rotor( $size => -$size + 1).grep: { [eq] $_ }# ((1 1) (2 2) (2 2) (4 4) (3 3)) আপনাকে কেবল $sizeবিভিন্ন দৈর্ঘ্যের সিকোয়েন্সগুলির জন্য সামঞ্জস্য করতে হবে ।
এলিজাবেথ ম্যাটিজসেন

হাই আবার @ লার্সমেলসটেন। দয়া করে এলএমকে আপনি যদি ভাবেন rotorযে আমি যুক্ত করেছি যে দুটি বিকল্প আমার উত্তরকে দুর্বল করেছে বা শক্তিশালী করেছে।
রায়ফ

rotorসমাধানটির পরিমার্জনিত সংস্করণ অর্থাত্ say @s.rotor(2=>-1).grep:{.[0]eq.[1]}স্বাগত because কারণ এটি উভয়ই খাটো ( rotorপদ্ধতি ব্যতীত সাধারণ সংস্করণগুলিকেও স্বাগত জানানো হয় কারণ তারা দেখায় যে কীভাবে কিছু quirks ব্যবহার করা হয় xxএবং কীভাবে :ovব্যবহৃত হয়। সুতরাং সমস্যাটি খুব ভালভাবে সমাধান হয়েছে :)
লার্স ম্যালমস্টিন

5

TIMTOWDI!

এখানে gather/ ব্যবহার করে একটি পুনরাবৃত্তি পদ্ধতি রয়েছে take

say gather for <1 1 0 2 0 2 1 2 2 2 4 4 3 3> { 
    state $last = ''; 
    take ($last, $_) if $last == $_; 
    $last = $_; 
};

# ((1 1) (2 2) (2 2) (4 4) (3 3))

উত্তরের জন্য ধন্যবাদ. এটি নিজের মতো করে বেশ সূক্ষ্ম দেখাচ্ছে। take ($last, $_)অংশ ব্যবহারের উপর একটি শালীন উদাহরণ gather and takeমানিকজোড়।
লার্স মলমসটিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.