এটি কি প্রকৃত বৃক্ষ?


20

আপনার এমন একটি প্রোগ্রাম বা ফাংশন লিখতে হবে যা ইনপুট হিসাবে আউটপুট এবং আউটপুট হিসাবে স্ট্রিং গ্রহণ করে অথবা ইনপুটটি ASCII ট্রি হলে ফিরে আসে।

  _
\/  /
 \_/
  |
  |

এএসসিআইআই গাছগুলিতে অক্ষর / \ | _ spacesএবং থাকে newlines

শ্বেতস্থানবিহীন অক্ষরগুলি একটি লাইন বিভাগ দ্বারা তাদের ঘরের দুটি প্রান্ত বিন্দু সংযুক্ত করে:

  • / নীচে বাম এবং উপরের ডান কোণগুলি সংযুক্ত করে
  • \ নীচের ডান এবং উপরে বাম কোণগুলি সংযুক্ত করে
  • | নীচের প্রান্ত এবং শীর্ষ প্রান্তের মধ্য পয়েন্টগুলি সংযুক্ত করে
  • _ নীচের বাম এবং নীচের ডান কোণ এবং নীচের প্রান্তের মাঝের পয়েন্টটি সংযুক্ত করে

(দ্রষ্টব্য, এর অর্থ এই যে |কেবল |বা এর সাথে সংযুক্ত হতে পারে _তবে /বা এর সাথে নয় \))

নিম্নলিখিত নিয়মগুলি প্রয়োগ করা হলে একটি এএসসিআইআই ছবিটিকে গাছ বলা হয়:

  • ঠিক এক অক্ষরের ঠিক এক বিন্দু (মূল) শেষ সারির নীচের প্রান্তে স্পর্শ করে।
  • আপনি যে কোনও লাইন বিভাগের যে কোনও বিন্দুতে পৌঁছাতে পারবেন:

    • মূল থেকে শুরু
    • কেবল রেখাংশগুলি ব্যবহার করে
    • কখনও নীচের দিকে যাবেন না (এমনকি নীচের দিকেও নয়)

ইনপুট

  • অক্ষর সমন্বিত একটি স্ট্রিং / \ | _ spaceএবং newlineকমপক্ষে একটি অ-হোয়াইটস্পেস অক্ষর সমন্বিত।
  • আপনি দুটি ইনপুট ফর্ম্যাট চয়ন করতে পারেন:

    • গাছের চারপাশে কোনও অপ্রয়োজনীয় সাদা স্থান নেই (উদাহরণগুলিতে দেখা যায়)।
    • সমস্ত সারি একই দৈর্ঘ্য তৈরি করতে সারির ডানদিকে ফাঁকা জায়গা বাদে গাছের চারপাশে কোনও অপ্রয়োজনীয় শ্বেতক্ষেত্র (উদাহরণগুলিতে দেখা যায়)।
  • ট্রেলিং নিউলাইন optionচ্ছিক।

আউটপুট

উদাহরণ

বৈধ গাছ:

|
  _
\/  /
 \_/
  |
  |
/ /    \/
\ \____/
 \/
 /
/
 \___/
 /   \
 \___/
   |
   |
   __/
 _/
/
____
  \  ___
 \ \/
  \/\_____/
 \/  \/
  \__/
    |
    |

অবৈধ গাছ (অতিরিক্ত ব্যাখ্যা সহ যা ইনপুটগুলির অংশ নয়):

\/
 \_______/
  \__   /
   | \_/    <- reachable only on with downward route
   |
_           <- multiple roots
\/          <- multiple root characters
/\          <- multiple roots
|           <- unreachable part

|
 __/
/           <- unreachable parts
|
\____/
 |  |       <- multiple roots
_\__/       <- unreachable parts (_ and \ don't connect to each other)
|

এটি কোড-গল্ফ তাই সংক্ষিপ্ত এন্ট্রি জিততে পারে।

উত্তর:


7

পিএমএ / শামুক , 99 93

এটি "ট্রি" সংজ্ঞাটি সন্তুষ্ট করে যদি 1 বা প্রিন্ট করে তবে 0 টি প্রিন্ট করে। ইনপুটটির আয়তক্ষেত্রাকার স্পেস-প্যাডযুক্ত ফর্মটি অগ্রাধিকার দেওয়া হয়, যদিও এটি Fর্যাগড সংস্করণটিকে স্থান-ভর্তি আয়তক্ষেত্রে রূপান্তর করতে কেবল একটি বাইট ( বিকল্প ব্যবহার করে ) খরচ করে , যা পরীক্ষায় কার্যকর ছিল।

&
\ |{(\_|\|)d=\||(\\a7|\/d|\_da7)=\\|(\\d|\/a5|\_da5)=\/|(\_lr|\|d|\/l|\\r)=\_},^_!(r.,^ )d~

অবরুদ্ধ, পুরানো সংস্করণ (আমার ব্যক্তিগত দেখার আনন্দের জন্য):

F&
\ |
{
  \_ (lr=\_|da5=\/|da7=\\|d=\|) | \/ (l=\_|a5=\/|d=\\) | 
    \\ (r=\_|a7=\\|d=\/) | \|d=(\_|\|)    
}, 
^_ !(r.,^ ) d~

এটি বর্তমান ভাষার বৈশিষ্ট্যগুলির সাথে মোটামুটি উপযুক্ত to দুর্ভাগ্যক্রমে, কাজ করতে পারার আগে আমাকে একটি রেফারেন্স কাউন্টিং বাগটি তাড়া করতে কয়েক ঘন্টা ব্যয় করতে হয়েছিল।

&বিকল্প মানে হল যে ম্যাচ প্রতিটি ভাষার প্রতিটি অক্ষরের এ সফল নয়। প্রতিটি অ-স্পেস শুরুর পয়েন্ট থেকে এটি নীচের দিকে একটি নিচের দিকে যাওয়ার জন্য পরীক্ষা করে। একটি রেইজেক্সের সাথে একটি সসীম স্টেট মেশিন তৈরি করা এখানে দৃ .়তার সাথে দৃ as়তা ব্যবহার করে ভাগ্যক্রমে অনেক খাটো হয় =। নীচের সারিতে এটি পরীক্ষা করে যে ডানদিকে কোনও ফাঁকা স্থান নেই।


10

গণিত, 345 300 বাইট by

এখনও বেশ দীর্ঘ, তবে আমার ধারণা এটি একটি শুরু ...

(s=StringSplit;v=Reverse;#=="|"||#=="\\"||#=="/"&[""<>s@#]&&(g={};i=0;(c={i,++j};d={i,j+1/2};e=2d-c;g=Join[g,Switch[#,"|",{d->{1,0}+d},"/",{c->c+1},"\\",{e->{i+1,j}},"_",{c->d,d->e,e->c},_,{}]])&/@Characters[++i;j=0;#]&/@{##};Sort@VertexOutComponent[Graph@g,g[[1,1]]]==Union@@List@@@g)&@@v@s[#,"
"])&

এখানে একটি সামান্য অবারিত সংস্করণ:

(
  s = StringSplit;
  v = Reverse;
  # == "|" || # == "\\" || # == "/" &[
      "" <> s@#
      ] && (
      g = {};
      i = 0;
      (
           c = {i, ++j};
           d = {i, j + 1/2};
           e = 2 d - c;
           g = Join[g, Switch[#,
              "|", {d -> {1, 0} + d},
              "/", {c -> c + 1},
              "\\", {e -> {i + 1, j}},
              "_", {c -> d, d -> e, e -> c},
              _, {}
              ]]
           ) & /@ Characters[
          ++i;
          j = 0;
          #
          ] & /@ {##};
      Sort@VertexOutComponent[Graph@g, g[[1, 1]]] == 
       Union @@ List @@@ g
      ) & @@ v@s[#, "\n"]
) &

এটি একটি নামবিহীন ফাংশন সংজ্ঞায়িত করে যা স্ট্রিংটিকে ইনপুট হিসাবে এবং রিটার্ন হিসাবে গ্রহণ করে Trueবা False

প্রাথমিক ধারণাটি প্রথমে একটি একক মূল রয়েছে কিনা তা যাচাই করা হয় এবং তারপরে সমস্ত অনুভূমিকটি মূল Graphথেকে পৌঁছানো যায় কিনা তা পরীক্ষা করার জন্য একটি আসল (নির্দেশিত) অবজেক্ট তৈরি করা উচিত। আমরা গ্রাফটি কীভাবে তৈরি করব তা এখানে:

ASCII শিল্পের উপরে একটি পূর্ণসংখ্যার গ্রিডের ওভারলাইডের কল্পনা করুন, যেখানে পূর্ণসংখ্যার স্থানাঙ্কগুলি চরিত্রের ঘরের কোণগুলির সাথে মিল রাখে। তারপরে প্রতিটি কক্ষে ছয়টি প্রাসঙ্গিক পয়েন্ট রয়েছে যা সংযুক্ত হতে পারে। এখানে একটি উদাহরণ, যেখানে আমি আরো পয়েন্ট লেবেল করেছি aকরতে f:

     |                 |
     |                 |
---(2,3)---(2.5,3)---(3,2)---
     | d      e      f |
     |                 |
     |                 |
     |                 |
     |                 |
     |                 |
     |                 |
     | a      b      c |
---(2,2)---(2.5,2)---(3,2)---
     |                 |
     |                 |

সুতরাং আমরা এমন একটি গ্রাফ তৈরি করতে পারি যার উল্লম্বগুলি এই অর্ধ-পূর্ণসংখ্যার স্থানাঙ্ক এবং যার প্রান্তগুলি ইনপুটটিতে অ ফাঁস অক্ষর দ্বারা নির্ধারিত হয়। |সাথে সংযোগ স্থাপন bকরে e, /সংযুক্ত aহয় fএবং \সংযুক্ত cহয় d। নোট করুন যে পরে গ্রাফটি ট্র্যাভার করার সময় আমরা কখনই নীচের দিকে অগ্রসর হইনি তা নিশ্চিত করতে এগুলি অবশ্যই প্রান্তগুলি নির্দেশিত হতে হবে। জন্য _আমরা উভয় ক্ষেত্রেই যেতে পারে, তাই তত্ত্ব আমরা চার প্রান্ত প্রয়োজন a -> b, b -> a, b -> c, c -> b। যাইহোক, আমরা লক্ষ্য আসতে পারে যা সমস্তই যে বিষয়ে সেখানে একটি চক্র সব তিনটি ছেদচিহ্ন ধারণকারী, তাই আমরা তিন প্রান্ত এই কমান পারে যে যে: a -> b, b -> c, c -> a

কারণ এই গ্রাফ নির্মাণের, ম্যাথামেটিকাল বেশ সহজ কোনো বস্তু, একটি প্রান্তবিন্দু হিসাবে কাজ করতে পারেন তাই আমি আসলে একটি গ্রাফ যার ছেদচিহ্ন নির্মাণ করতে পারেন হয় তুল্য জোড়া।

অবশেষে, আমরা পরীক্ষা করে দেখি যে প্রতিটি ভার্টেক্সটি মূল থেকে পৌঁছানো যায়। মূলের স্থানাঙ্কটি গ্রাফের সাথে যুক্ত হওয়া প্রথম প্রথম ভার্টেক্স হিসাবে সহজেই পাওয়া যায়। তারপরে আমি যে সংক্ষিপ্ততম পদ্ধতিটি দেখেছি যে সমস্ত অনুভূমিকায় পৌঁছতে পারে কিনা তা পরীক্ষা করে দেখতে VertexOutComponentহবে যে গ্রাফের সমস্ত উল্লম্বের সেটের মূলের (যেমন মূল থেকে সমস্ত অক্ষের সেটটি পৌঁছনীয়) সেটটি সমান কিনা check


1
300 বাইট দীর্ঘ হতে পারে, তবে ঠিক 300 তত সন্তুষ্টিক!
অ্যালেক্স এ।

2

রুবি 226 227 228

->i{w=i.index(?\n)+1
t=[i.index(/[^ _] *\n\z/)]
a=->x,c{(i[x]==c||i[x]==?_)&&t<<x}
((x=t.pop)&&(s=x-w;c=i[x])<?0?(a[s+1,?/];a[s,?\\]):c<?]?(a[s-1,?\\];a[s,?/]):c<?`?(a[x-1,?\\];a[x+1,?/]):a[s,?|]
i[x]=' ')while t!=[]
!i[/\S/]}

অনলাইন পরীক্ষা: http://ideone.com/Z7TLTt

প্রোগ্রামটি নিম্নলিখিতগুলি করে:

  • একটি রুট এর জন্য অনুসন্ধান (ক \, /বা |শেষ সারি দিকে)
  • এই মূল থেকে শুরু করে, নিয়মগুলি ব্যবহার করে গাছটিতে আরোহণ করুন এবং প্রতিটি পরিদর্শন করা চরকে একটি স্থান দিয়ে প্রতিস্থাপন করুন
  • শেষে, দেখুন যে আমাদের স্ট্রিং পুরোপুরি শ্বেত স্পেস দিয়ে গঠিত (অর্থাত্ একটি বৈধ গাছ), বা না (অবৈধ গাছ; সমস্ত টুকরা "পরিদর্শন করা হয়নি")

এখানে এটি নিয়ন্ত্রিত:

F =-> input {
  row_size = input.index(?\n)+1

  root_coord = input.index /[^ _] *\n\z/

  # coordinates to process
  todo = [root_coord]

  add_todo = -> coord, char{
    if input[coord] == char || input[coord] == ?_
      todo << coord
    end
  }

  while todo.any?
    x = todo.pop

    next unless x # exit quickly if no root present

    case input[x]
    when ?|
      add_todo[x - row_size, ?|]
    when ?_
      add_todo[x - 1, ?\\]
      add_todo[x + 1, ?/]
    when ?/
      add_todo[x - row_size + 1, ?/]
      add_todo[x - row_size, ?\\]
    when ?\\
      add_todo[x - row_size - 1, ?\\]
      add_todo[x - row_size, ?/]
    end
    input[x]=' '
  end
  input.strip < ?*
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.