সোয়াইপ ধরণের রূপান্তরকারী


27

ল্যাপটপে টাইপ করার পরবর্তী বিপ্লবটি সুইফটকে ২০১৪ সালের প্রথম এপ্রিল প্রকাশ করেছিল । যাইহোক, আমি একটি সোয়াইপিং ন্যানো ক্লোন লেখার প্রথম ব্যক্তি হতে চাই, কিন্তু, আমি বাস্তব-পাঠ্য লাইব্রেরিতে একটি ভাল সোয়াইপ-পাঠ্য খুঁজে পাচ্ছি না এবং আমি তাদের জন্য অপেক্ষা করতে পারি না, আমি এখানে জিজ্ঞাসা করছি।

কার্য

সোয়াইপ-পাঠ্য গ্রহণ করে এমন একটি প্রোগ্রাম লিখুন এবং আসল পাঠ্যের সমতুল্য আউটপুট দেয়। উদাহরণ:

Input: hgrerhjklo
Output: hello

ব্যবহারকারী যখন:

এখানে চিত্র বর্ণনা লিখুন

অন্যান্য উদাহরণ:

Input: wertyuioiuytrtjklkjhgfd
Output: world

Input: poiuytrtyuioiugrewsasdfgbhnmkijnbg
Output: programming

Input: poiuygfdzxcvhjklkjhgres
Output: puzzles

Input: cvhjioiugfde
Output: code

Input: ghiolkjhgf
Output: golf

বিধি

  • প্রোগ্রামটি স্টিডিন বা আরজিভিতে একটি সোয়াইপ করা 'শব্দ' নেবে
  • সোয়াইপ করা ইনপুটটির প্রথম এবং শেষ বর্ণটি আসল শব্দের প্রথম এবং শেষ বর্ণের সমান হবে
  • আপনি ধরে নিতে পারেন যে ব্যবহারকারী যথাযথভাবে সরল রেখাগুলি তৈরি করবেন তবে আপনি এটি যাচাই করতে নমুনা ডেটা ব্যবহার করতে পারেন (আমি নমুনা ডেটা তৈরি করেছি এবং আমি চূড়ান্ত পরীক্ষার ডেটা করব)
  • অস্পষ্ট ইনপুটটির জন্য, আপনি উভয় আউটপুট নির্বাচন করতে পারেন, তবে আমি পরীক্ষার ডেটা থেকে সমস্ত অস্পষ্টতা মুছে ফেলার চেষ্টা করব
  • এই শব্দটি এই শব্দ তালিকায় থাকবে (তবে সোয়েপ করা হবে)। শব্দের তালিকাটি বর্তমান ডিরেক্টরিতে থাকবে এবং পড়তে পারা যাবে (নতুন রেখা পৃথক করা হবে wordlist, নাম দেওয়া হবে , কোনও এক্সটেনশন হবে না )।
  • সোয়াইপগুলিতে কেবল ছোট বর্ণমালার অক্ষর থাকবে
  • সোয়াইপে ডুপ্লিকেট করা অক্ষর থাকতে পারে, যদি ব্যবহারকারী কোনও কীতে বিরতি দেয়
  • প্রোগ্রামটি অবশ্যই স্টাডআউটে আউটপুট আউট করবে (কেস কোনও ব্যাপার নয়)
  • প্রোগ্রামটি অবশ্যই 0রিটার্ন কোড হিসাবে ফিরে আসতে হবে
  • আপনাকে অবশ্যই রান কমান্ড, সংকলন কমান্ড (প্রয়োজনে), নাম এবং কোনও ইনপুট পাথটি ব্যবহার করতে হবে
  • স্ট্যান্ডার্ড লুফোলগুলি প্রয়োগ হয় (যদিও তারা সাহায্য নাও করতে পারে)
  • কোনও অন্তর্নির্মিত গ্রন্থাগার অনুমোদিত নয়
  • নির্ধারক, অ গল্ফযুক্ত / অবলম্বনযুক্ত সমাধানগুলি পছন্দ করা হয়
  • ফাইল রাইটিং, নেটওয়ার্কিং ইত্যাদি নেই
  • আপনার কোডটি অবশ্যই এক সেকেন্ড বা তার চেয়ে কম চলতে হবে (আপনার কোড প্রতি শব্দে একবার চালানো হবে)
  • স্কোরিং রানগুলি 4 টি ভার্চুয়াল কোড (2 রিয়েল রিয়েল) সহ একটি ইন্টেল আই 7 হ্যাসওয়েল প্রসেসরে চালিত হয়, তাই আপনি যদি থ্রেড ব্যবহার করতে পারেন তবে
  • সর্বোচ্চ কোড দৈর্ঘ্য 5000 বাইট
  • আপনি যে ভাষাটি ব্যবহার করেন তা লিনাক্সের জন্য একটি নিখরচায় (বিনা বিচারে) সংস্করণ থাকতে হবে (আর্চ লিনাক্স, যদি তা গুরুত্বপূর্ণ হয়)

বিজয়ী মানদণ্ড

  • বিজয়ী সবচেয়ে সঠিক সমাধান ( সরবরাহিত পরীক্ষার তালিকা ব্যবহার করে নিয়ন্ত্রণ প্রোগ্রাম দ্বারা গোল )
  • জনপ্রিয়তা টাই ব্রেকার
  • স্কোরিং সারণী প্রতি কয়েকদিন আপডেট করা হবে
  • সময়-আউট এবং ক্র্যাশগুলি ব্যর্থ হিসাবে গণনা করে
  • জনপ্রিয়তার উপর নির্ভর করে এই চ্যালেঞ্জটি দুই সপ্তাহ বা তার বেশি সময় চলবে
  • চূড়ান্ত স্কোরিং শব্দের একটি পৃথক, এলোমেলোভাবে নির্বাচিত তালিকা ব্যবহার করবে (একই শব্দের তালিকা থেকে একই দৈর্ঘ্য)

অন্যান্য

  • আপনি আপনার প্রোগ্রামটি পরীক্ষা করতে নিয়ন্ত্রণ প্রোগ্রামটি ব্যবহার করতে পারেন
  • যদি আপনি অধৈর্য হয়ে থাকেন এবং আপনার প্রোগ্রামটি আপডেট / দ্রুত যুক্ত হতে চান তবে একটি সমস্যা শুরু করুন বা https://github.com/matjoyce/codegolf-swipe-type/blob/master এ অনুরোধটি টানুন
  • এন্ট্রিগুলি https://github.com/matjoyce/codegolf-swipe-type/blob/master/entries এ বজায় রাখা হয়
  • প্রতিটি প্রোগ্রাম পরিচালিত লগগুলি https://github.com/matjoyce/codegolf-swipe-type/blob/master/logs এ বজায় রাখা হয়
  • Https://github.com/matjoyce/codegolf-swipe-type/blob/master/log.log এ মূল লগ
  • keypos.csvX এবং y এর সাথে মান হিসাবে বর্ণিত বর্তমান ডিরেক্টরিতে প্রতিটি কী এর অবস্থান সিএসভি ফাইল হিসাবে সরবরাহ করা হবে Q(দেখুন https://github.com/matjoyce/codegolf- সুইপ-type/blob/master/ keypos.csv )
  • প্রতিটি কী 1.5 x 1.5 সেমি (কীপোস.সিএসভি-তে একই ইউনিট)

বর্তমান স্কোর বোর্ড

টেস্টলিস্ট ( লগ ):

Three Pass Optimizer:Errors: 0/250       Fails: 7/250        Passes: 243/250     Timeouts: 0/250     
Corner Sim:         Errors: 0/250       Fails: 9/250        Passes: 241/250     Timeouts: 0/250     
Discrete Fréchet Distance:Errors: 0/250       Fails: 17/250       Passes: 233/250     Timeouts: 0/250     
Turnaround:         Errors: 0/250       Fails: 18/250       Passes: 232/250     Timeouts: 0/250     
Direction Checker:  Errors: 0/250       Fails: 19/250       Passes: 231/250     Timeouts: 0/250     
Regex Solver:       Errors: 0/250       Fails: 63/250       Passes: 187/250     Timeouts: 0/250

টেস্টলিস্ট 2 ( লগ ):

Corner Sim:         Errors: 0/250       Fails: 10/250       Passes: 240/250     Timeouts: 0/250     
Three Pass Optimizer:Errors: 2/250       Fails: 14/250       Passes: 234/250     Timeouts: 0/250     
Turnaround:         Errors: 0/250       Fails: 16/250       Passes: 234/250     Timeouts: 0/250     
Direction Checker:  Errors: 0/250       Fails: 17/250       Passes: 233/250     Timeouts: 0/250     
Discrete Fréchet Distance:Errors: 0/250       Fails: 18/250       Passes: 232/250     Timeouts: 0/250     
Regex Solver:       Errors: 0/250       Fails: 67/250       Passes: 183/250     Timeouts: 0/250

ফাইনাল রান

টেস্টলিস্ট ( লগ ):

Corner Sim:         Errors: 0/250       Fails: 14/250       Passes: 236/250     Timeouts: 0/250     
Three Pass Optimizer:Errors: 0/250       Fails: 18/250       Passes: 232/250     Timeouts: 0/250     
Direction Checker:  Errors: 0/250       Fails: 20/250       Passes: 230/250     Timeouts: 0/250     
Turnaround:         Errors: 0/250       Fails: 23/250       Passes: 227/250     Timeouts: 0/250     
Discrete Fréchet Distance:Errors: 0/250       Fails: 30/250       Passes: 220/250     Timeouts: 0/250     
Regex Solver:       Errors: 0/250       Fails: 55/250       Passes: 195/250     Timeouts: 0/250

প্রত্যেকের সাথে ভাল কাজ করেছেন এবং hgfdsasdertyuiopoiuy swertyuiopoijnhg!


"একটি সমাধান" কী? এর কোড কোথায়?
ডুরকনব



@Optimizer না নিশ্চিত অন্যান্য ক্ষেত্রে, কিন্তু সম্বন্ধে " পি oiuytres একটি SE স্প্যানিশ ভাষায় একটি গুলি fghui iugfd এক্স cgu আমি UG XS একটি sdfghjk Ku Y " অনুক্রমে এর "আপাতদৃষ্টে বিপরীত মনে হলেও", যে অক্ষর, ব্যতীত রয়েছে l, যা দ্বিগুণ হয় না।
es1024

1
@ ওপটিমাইজার ওয়েল, আমি ভেবেছিলাম আপনার জমাটি এটি পরাজিত করবে, তবে এটি কেবল নীচে ছিল (একটু টুইট করার ফলে সেটি বদলে যেতে পারে, আমি নিশ্চিত)। দেখে মনে হচ্ছে আমি এটি গ্রহণ করতে পারি, সুতরাং ... আমি কি (এটি স্বীকার করে রেপ পেতে উপস্থিত হই না)? আমি অন্য কারও গ্রহণ করতে চাই, তবে এটি নিয়মগুলি অনুসরণ করছে না (যদি না আপনি ভাল ধারণা পান)।
matsjoyce

উত্তর:


12

জাভাস্ক্রিপ্ট, ES6, থ্রি পাস অপ্টিমাইজার, 112 187 235 240 241 243 এবং 231 234 পাস

একটি তিনটি পাস ফিল্টার যা প্রথমে কীস্ট্রোক অনুক্রমের সমালোচনামূলক কীগুলি বের করে এবং তারপরে তিনটি ফিল্টারের মধ্য দিয়ে ক্রমটি পাস করে:

  1. সমালোচনামূলক কী এবং সহায়তা কীগুলি থেকে একটি আলগাভাবে গঠিত RegEx। এটি বেশিরভাগ কীগুলির জন্য সঠিক ফলাফল দেয় (প্রায় 150)
  2. একটি কঠোর RegEx মাত্র সমালোচনা কী থেকে তৈরি। এটি অতিরিক্ত 85 সিকোয়েন্সের জন্য সঠিক ফলাফল দেয়
  3. কাছাকাছি জবাবগুলির মধ্যে অস্পষ্টতা খুঁজে বের করার জন্য একটি তৃতীয় ফিল্টার। এটি 40% অস্পষ্ট ক্ষেত্রে কাজ করে।

কোড

keyboard = {
  x: {},
  y: ['  q      w      e      r      t      y      u      i      o      p',
      '    a      s      d      f      g      h      j      k      l',
      '        z      x      c      v      b      n      m'],
};
for (var i in keyboard.y)
  for (var y of keyboard.y[i])
    keyboard.x[y] = +i*7;
p = C => (x=keyboard.x[C],{x, y: keyboard.y[x/7].indexOf(C)})
angle = (L, C, R) => (
  p0 = p(L), p1 = p(C), p2 = p(R),
  a = Math.pow(p1.x-p0.x,2) + Math.pow(p1.y-p0.y,2),
  b = Math.pow(p1.x-p2.x,2) + Math.pow(p1.y-p2.y,2),
  c = Math.pow(p2.x-p0.x,2) + Math.pow(p2.y-p0.y,2),
  Math.acos((a+b-c) / Math.sqrt(4*a*b))/Math.PI*180
)
corner = (L, C, R, N, W) => {
  if (skip) {
    skip = false;
    return [];
  } 
  ngl = angle(L, C, R);
  if (ngl < 80) return [C + "{1,3}"]
  if (ngl < 115 && p(L).x != p(R).x && p(L).x != p(C) && p(R).x != p(C).x && Math.abs(p(L).y - p(R).y) < 5) return [C + "{0,3}"]
  if (ngl < 138) {
    if (N && Math.abs(ngl - angle(C, R, N)) < 6) {
      skip = true;
      return [L + "{0,3}", "([" + C + "]{0,3}|[" + R + "]{0,3})?", N + "{0,3}"]
    }
    return [C + "{0,3}"]
  }
  return ["([" + L + "]{0,3}|[" + C + "]{0,3}|[" + R + "]{0,3})?"]
}
f = S => {
  for (W = [S[0] + "{1,2}"],i = 1; i < S.length - 1; i++)
    W.push(...corner(S[i - 1], S[i], S[i + 1], S[i + 2], W))
  return [
    new RegExp("^" + W.join("") + S[S.length - 1] + "{1,3}$"),
    new RegExp("^" + W.filter(C=>!~C.indexOf("[")).join("") + S[S.length - 1] + "{1,3}$")
  ]
}
thirdPass = (F, C) => {
  if (!F[0]) return null
  F = F.filter((s,i)=>!F[i - 1] || F[i - 1] != s)
  FF = F.map(T=>[...T].filter((c,i)=>!T[i - 1] || T[i - 1] != c).join(""))
  if (FF.length == 1) return F[0];
  if (FF.length < 6 && FF[0][2] && FF[1][2] && FF[0][0] == FF[1][0] && FF[0][1] == FF[1][1])
    if (Math.abs(F[0].length - F[1].length) < 1)
      for (i=0;i<Math.min(F[0].length, FF[1].length);i++) {
        if (C.indexOf(FF[0][i]) < C.indexOf(FF[1][i])) return F[0]
        else if (C.indexOf(FF[0][i]) > C.indexOf(FF[1][i])) return F[1]
      }
  return F[0]
}
var skip = false;
SwiftKey = C => (
  C = [...C].filter((c,i)=>!C[i - 1] || C[i - 1] != c).join(""),
  skip = false, matched = [], secondPass = [], L = C.length, reg = f(C),
  words.forEach(W=>W.match(reg[0])&&matched.push(W)),
  words.forEach(W=>W.match(reg[1])&&secondPass.push(W)),
  matched = matched.sort((a,b)=>Math.abs(L-a.length)>Math.abs(L-b.length)),
  secondPass = secondPass.sort((a,b)=>Math.abs(L-a.length)>Math.abs(L-b.length)),
  first = matched[0], second = secondPass[0], third = thirdPass(secondPass.length? secondPass: matched, C),
  second && second.length >= first.length - 1? first != third ? third: second: third.length >= first.length ? third: first
)

// For use by js shell of latest firefox
print(SwiftKey(readline()));

কোডটি একটি ভেরিয়েবল wordsবর্তমান বলে ধরে নিয়েছে যা এই পৃষ্ঠা থেকে সমস্ত শব্দের একটি অ্যারে রয়েছে

এখানে কর্মের কোডটি দেখুন

কর্মক্ষেত্রে পরীক্ষার কেসগুলি এখানে দেখুন

উপরের উভয় লিঙ্কটি কেবলমাত্র একটি সর্বশেষতম ফায়ারফক্সে (33 এবং উপরে) (ইএস 6 এর কারণে) কাজ করে।


হা! আমি শাঁস দিয়ে গুলি চালাচ্ছি। আপনি keypos.csvএখন সঠিক ফাইলটিও ব্যবহার করতে পারেন । আই অনুষ্ঠান তালিকাভুক্ত করা হয় avalible developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/...
matsjoyce

এটি ঠিক আছে, তবে সোয়াইপগুলি আমার কীবোর্ডের কোণগুলি দিয়ে তৈরি করা হয়েছে, সুতরাং এটি আপনার পছন্দ (যদিও আপনার স্কোরটি প্রভাবিত হয়েছে বলে মনে হয় না!)
matsjoyce


২৪০ জন পাস! আমি ভাবতাম যে অস্পষ্টতাগুলি এই জাতীয় ভাল ফলাফলকে আটকাবে। আমি কৌতূহল হব কিভাবে এটি চূড়ান্ত পরীক্ষার সেটটিতে পারফর্ম করবে।
এমিল

@ এমিল - হ্যাঁ, আমিও এটি দেখার জন্য অপেক্ষা করছি।
অপ্টিমাইজার

9

রুবি, রেজেক্স সলভার - 30 140 176 180 182 187 এবং 179 183 পাস

আমি পরে স্কোর বের করব। এখানে খুব নিষ্পাপ সমাধান যা কীবোর্ড বিন্যাসটিকে বিবেচনায় নেয় না:

words = File.readlines('wordlist').map(&:chomp)

swipe = ARGV.shift
puts words.select {|word| word[0] == swipe[0] &&
                          word[-1] == swipe[-1]}
          .select {|word|
              chars = [word[0]]
              (1..word.size-1).each {|i| chars << word[i] if word[i] != word[i-1]}
              swipe[Regexp.new('^'+chars.join('.*')+'$')]
          }.sort_by {|word| word.size}[-1]

এটি এআরজিভি থেকে ইনপুট নেয় এবং ফলাফল মুদ্রণ করে। আমি কেবল প্রথম এবং শেষ অক্ষরের মাধ্যমে শব্দের তালিকাটি ফিল্টার করছি, এবং সেগুলি আমি বাকী সমস্ত শব্দের চেষ্টা করছি ইনপুটটির বিরুদ্ধে (সদৃশ অক্ষরগুলি মুছে ফেলা এবং ^g.*u.*e.*s$"অনুমান" এর জন্য একটি রেজিেক্স ব্যবহার করে ) এবং সেখানে যদি প্রথমটি ফিরে আসে তবে একাধিক সমাধান।

এটি চালান

ruby regex-solver.rb cvhjioiugfde

অন্য যে কেউ, এই পদক্ষেপটিকে প্রথম ফিল্টার হিসাবে পুনঃব্যবহার করতে দ্বিধা বোধ করবেন - আমি বিশ্বাস করি এটি কোনও সঠিক শব্দ ফেলে দেবে না, তাই এই প্রাথমিক চেকটি আরও ভাল অ্যালগরিদমের জন্য অনুসন্ধানের স্থানটিকে হ্রাস করতে পারে।

সম্পাদনা করুন: ওপিএসের পরামর্শ অনুসরণ করে আমি এখন দীর্ঘতম প্রার্থী নির্বাচন করছি, যা মনে হয় শালীন বৈকল্পিক।

অনুরূপ চিঠি সম্পর্কে আমাকে মনে করিয়ে দেওয়ার জন্য es1024 ধন্যবাদ।


সম্পন্ন. আপনার লগটি github.com/matjoyce/codegolf-swipe-type/blob/master/logs/… এ আমার মনে হয় যে সমস্যাটি এলোমেলোভাবে সম্ভাব্য সমাধানগুলি থেকে নির্বাচন করে, যা দীর্ঘতম বা অন্য কিছু নির্বাচন করে উন্নত করা যেতে পারে।
ম্যাটসজয়

আমি মনে করি এটি একে অপরের পাশে দুটি অভিন্ন অক্ষর সহ সমস্ত সঠিক শব্দ ফেলে দিতে পারে paradoxically, যেমন lরেজিটেক্সের দ্বার চেয়ে দ্বিগুণ চেয়ে কেবল ইনপুটে একবার প্রদর্শিত হবে।
es1024

@ এস 1024, আহ ধন্যবাদ, আমি যখন প্রথম এই সারণী বাক্সে এই অ্যালগরিদমটি প্রস্তাব করলাম তখন আমি আসলে সে সম্পর্কে সচেতন ছিলাম, তবে গতকাল এটি ভুলে গিয়েছিলাম। পরে ঠিক করবে।
মার্টিন এন্ডার

7

সি ++, ডিসকাউন্ট ফ্র্যাচেট দূরত্ব - 201 220 222 232 এবং 232 টি পাস

আমার কাছে, সমস্যাটি ফ্রেঞ্চ দূরত্বের জন্য ডেকে আনে যা দুর্ভাগ্যক্রমে গণনা করা খুব কঠিন।

কেবল মজাদার জন্য, আমি কম্পিউটারের ডিস্ক্রিট ফ্র্যাচেট দূরত্বের (১৯৯৪) টমাস ইটার এবং হাইক্কি মান্নিলা বর্ণিত একটি স্বতন্ত্র সান্নিধ্যে প্রয়োগ করে সমস্যার দিকে এগিয়ে যাওয়ার চেষ্টা করেছি ।

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

এখনও অবধি, পদ্ধতিটি যেমন আশা করেছিলাম তেমন কার্যকর হয় না (এটি "কোড" হিসাবে কোড উদাহরণটি স্বীকৃতি দেয়) তবে এটি কেবল এখনও খুঁজে পাওয়া যায় নি এমন বাগগুলির ফলাফল হতে পারে। অন্যথায়, আরেকটি ধারণা হ'ল হ'ল দূরত্বের অন্যান্য প্রকরণগুলি ("সর্বাধিক কুকুরের ছাঁটাই দৈর্ঘ্যের" পরিবর্তে "গড়") ব্যবহার করা।

সম্পাদনা: এখন, আমি "গড় কুকুর ফাঁস দৈর্ঘ্য" এর একটি অনুমান ব্যবহার করছি। এর অর্থ হ'ল আমি উভয় পাথের মধ্যে একটি অর্ডারযুক্ত ম্যাপিং সন্ধান করছি যা সমস্ত দূরত্বের যোগফলকে হ্রাস করে এবং পরে এটি দূরত্বের সংখ্যার দ্বারা ভাগ করে।

অভিধানের শব্দটিতে একই অক্ষরটি যদি দু'বার বা তার বেশি বার দেখা যায় তবে আমি কেবল একটি নোড পথে রেখেছি।

#include<iostream>
#include<fstream>
#include<vector>
#include<map>
#include<algorithm>
#include<utility>
#include<cmath>

using namespace std;

const double RESOLUTION = 3.2;

double dist(const pair<double, double>& a, const pair<double, double>& b) {
    return sqrt((a.first - b.first) * (a.first - b.first) + (a.second - b.second) * (a.second - b.second));
}

double helper(const vector<pair<double, double> >& a,
        const vector<pair<double, double> >& b,
        vector<vector<double> >& dp,
        int i,
        int j) {
    if (dp[i][j] > -1)
        return dp[i][j];
    else if (i == 0 && j == 0)
        dp[i][j] = dist(a[0], b[0]);
    else if (i > 0 && j == 0)
        dp[i][j] = helper(a, b, dp, i - 1, 0) +
                   dist(a[i], b[0]);
    else if (i == 0 && j > 0)
        dp[i][j] = helper(a, b, dp, 0, j - 1) +
                   dist(a[0], b[j]);
    else if (i > 0 && j > 0)
        dp[i][j] = min(min(helper(a, b, dp, i - 1, j),
                           helper(a, b, dp, i - 1, j - 1)),
                       helper(a, b, dp, i, j - 1)) +
                   dist(a[i], b[j]);
    return dp[i][j];
}

double discretefrechet(const vector<pair<double, double> >& a, const vector<pair<double, double> >& b) {
    vector<vector<double> > dp = vector<vector<double> >(a.size(), vector<double>(b.size(), -1.));
    return helper(a, b, dp, a.size() - 1, b.size() - 1);
}

bool issubsequence(string& a, string& b) {
    // Accounts for repetitions of the same character: hallo subsequence of halo
    int i = 0, j = 0;
    while (i != a.size() && j != b.size()) {
        while (a[i] == b[j])
            ++i;
        ++j;
    }
    return (i == a.size());
}

int main() {
    string swipedword;
    cin >> swipedword;

    ifstream fin;
    fin.open("wordlist");
    map<string, double> candidatedistance = map<string, double>();
    string readword;
    while (fin >> readword) {
        if (issubsequence(readword, swipedword) && readword[0] == swipedword[0] && readword[readword.size() - 1] == swipedword[swipedword.size() - 1]) {
            candidatedistance[readword] = -1.;
        }
    }
    fin.close();

    ifstream fin2;
    fin2.open("keypos.csv");
    map<char, pair<double, double> > keypositions = map<char, pair<double, double> >();
    char rc, comma;
    double rx, ry;
    while (fin2 >> rc >> comma >> rx >> comma >> ry) {
        keypositions[rc] = pair<double, double>(rx, ry);
    }
    fin2.close();

    vector<pair<double, double> > swipedpath = vector<pair<double, double> >();
    for (int i = 0; i != swipedword.size(); ++i) {
        swipedpath.push_back(keypositions[swipedword[i]]);
    }

    for (map<string, double>::iterator thispair = candidatedistance.begin(); thispair != candidatedistance.end(); ++thispair) {
        string thisword = thispair->first;
        vector<pair<double, double> > thispath = vector<pair<double, double> >();
        for (int i = 0; i != thisword.size() - 1; ++i) {
            pair<double, double> linestart = keypositions[thisword[i]];
            pair<double, double> lineend = keypositions[thisword[i + 1]];
            double linelength = dist(linestart, lineend);
            if (thispath.empty() || linestart.first != thispath[thispath.size() - 1].first || linestart.second != thispath[thispath.size() - 1].second)
                thispath.push_back(linestart);
            int segmentnumber = linelength / RESOLUTION;
            for (int j = 1; j < segmentnumber; ++j) {
                thispath.push_back(pair<double, double>(linestart.first + (lineend.first - linestart.first) * ((double)j) / ((double)segmentnumber),
                                    linestart.second + (lineend.second - lineend.second) * ((double)j) / ((double)segmentnumber)));
            }
        }
        pair<double, double> lastpoint = keypositions[thisword[thisword.size() - 1]];
        if (thispath.empty() || lastpoint.first != thispath[thispath.size() - 1].first || lastpoint.second != thispath[thispath.size() - 1].second)
        thispath.push_back(lastpoint);

        thispair->second = discretefrechet(thispath, swipedpath) / (double)(thispath.size());
    }

    double bestscore = 1e9;
    string bestword = "";
    for (map<string, double>::iterator thispair = candidatedistance.begin(); thispair != candidatedistance.end(); ++thispair) {
        double score = thispair->second;
        if (score < bestscore) {
            bestscore = score;
            bestword = thispair->first;
        }
        // cout << thispair->first << ": " << score << endl;
    }
    cout << bestword << endl;

    return 0;
}

আমি ঝাঁকুনির সাথে কোডটি সংকলন করেছি, তবে g++ ./thiscode.cpp -o ./thiscodeএটিও ঠিকঠাক কাজ করা উচিত।


1
হ্যাঁ! শেষ পর্যন্ত কেউ একটি বড় ফ্যাট অ্যালগরিদম নাম সহ একটি সমাধান যুক্ত করেছেন! আপনার লগটি github.com/matjoyce/codegolf-sipipe-type/blob/master/logs/…
matsjoyce

1
এর পরিবর্তে এটিকে একটি বড় ফ্যাট কম্পিউটার বিজ্ঞানের সমস্যার জন্য একটি সাধারণ গতিশীল প্রোগ্রামিং অ্যালগরিদম বলি।
13:57 এ 17

কোনও কারণে, এটি ইনপুটটির জন্য ব্যর্থ বলে মনে হচ্ছে programmijng- এটি আমাকে দেয় pang
Riking

এটা অদ্ভুত. আমি programmingএটি করা উচিত মত হচ্ছে । আপনি কি দয়া করে লাইনটি অসুবিধে // cout << thispair->first << ": " << score << endl;করে ফলাফলগুলি স্কোর করতে পারেন?
16:54

6

পাইথন 2, টার্নারাউন্ডস, 224 226 230 232 এবং 230 234 পাস করে

এটি বেশ সরলভাবে এগিয়ে আসা পদ্ধতির:

  • অক্ষরের প্রবাহটি দিক পরিবর্তন করে এমন পয়েন্টগুলি সন্ধান করুন (প্লাস শুরু এবং শেষ)।
  • দীর্ঘতম শব্দটি আউটপুট করুন যার মধ্যে এই সমস্ত টার্নিং পয়েন্ট রয়েছে।
import sys, csv, re

wordlistfile = open('wordlist', 'r')
wordlist = wordlistfile.read().split('\n')

layout = 'qwertyuiop asdfghjkl  zxcvbnm'
keypos = dict((l, (2*(i%11)+i/11, i/11)) for i,l in enumerate(layout))

#read input from command line argument
input = sys.argv[1]

#remove repeated letters
input = ''.join(x for i,x in enumerate(input) if i==0 or x!=input[i-1])

#find positions of letters on keyboard
xpos = map(lambda l: keypos[l][0], input)
ypos = map(lambda l: keypos[l][1], input)

#check where the direction changes (neglect slight changes in x, e.g. 'edx')
xpivot = [(t-p)*(n-t)<-1.1 for p,t,n in zip(xpos[:-2], xpos[1:-1], xpos[2:])]
ypivot = [(t-p)*(n-t)<0 for p,t,n in zip(ypos[:-2], ypos[1:-1], ypos[2:])]
pivot = [xp or yp for xp,yp in zip(xpivot, ypivot)]

#the first and last letters are always pivots
pivot = [True] + pivot + [True]

#build regex
regex = ''.join(x + ('+' if p else '*') for x,p in zip(input, pivot))
regexobj = re.compile(regex + '$')

#find all words that match the regex and output the longest one
words = [w for w in wordlist if regexobj.match(w)]
output = max(words, key=len) if words else input
print output

হিসাবে চালান

python turnarounds.py tyuytrghn

সমাধানটি খুব মজবুত নয়। একটি একক ভুল কীস্ট্রোক এটিকে ব্যর্থ করে তুলবে। যাইহোক, পরীক্ষার কেসগুলির সেটটি খুব ভালভাবেই কোনও ভুল বানান বানায় না, কেবলমাত্র এমন কিছু ক্ষেত্রে বিভ্রান্ত হয়ে পড়ে যেখানে এটি খুব দীর্ঘ শব্দ ব্যবহার করে।

সম্পাদনা: প্রদত্ত কী অবস্থানের ফাইলটি না, সরলিকৃত বিন্যাসটি ব্যবহার করতে আমি এটি কিছুটা পরিবর্তন করেছি। এটি আমার অ্যালগরিদমের পক্ষে সহজ করে তোলে কারণ ফাইলগুলিতে কীগুলি সমানভাবে ফাঁক হয় না। অস্পষ্ট ক্ষেত্রে কিছু অ্যাডহক টাইব্রেকারকে অন্তর্ভুক্ত করে আমি আরও কিছুটা ভাল ফলাফল অর্জন করতে পারি, তবে এটি এই নির্দিষ্ট পরীক্ষার সেটটির জন্য অতিরিক্ত-অনুকূল হবে। কিছু ব্যর্থতা রয়ে যায় যা আসলে অস্পষ্ট নয় তবে আমি আমার সাধারণ অ্যালগরিদমটি ধরিনা কারণ এটি কেবল 90 ডিগ্রিরও বেশি দিক পরিবর্তন বিবেচনা করে।


সাবাশ! বর্তমান নেতা! আপনি যদি লগটি দেখতে চান, গিতো গিথুব.ম্যাটজয়স
কোডোগল্ফ- সোয়াইপ-

@matjoyce: আমি মনে করি আমি যে দুটি বানান ভুল পেয়েছি তা খুঁজে পেয়ে প্রশ্নটিতে একটি মন্তব্য যুক্ত করেছি। :)
এমিল

হ্যাঁ, ধন্যবাদ, আমি এটিকে আরও একটি চেক দিচ্ছি। যদিও আমি দ্বিধাহীন মামলার সাথে কি করব তা পুরোপুরি নিশ্চিত নই।
ম্যাটসজয়স

@ formatjoyce: কীবোর্ড জুড়ে সম্ভাব্য পথগুলির মধ্যে একটি বেছে নিয়ে কিছু অস্পষ্টতা সমাধান করা যেতে পারে। যেমন bratsহতে পারে 'bgrdsasdrtrds'যা নিয়ে বিভ্রান্ত হতে পারে না breasts। যাইহোক, আপনি এটি যেমনটি রেখে দিচ্ছেন তাতেও আমি কিছু মনে করব না।
এমিল 21

সত্য, এটি কাজ করবে। আমি কেবল উদ্বিগ্ন যে এই সেটটি যদি খুব 'অনুকূল' করা হয় এবং চূড়ান্ত স্কোরিং সেটটি খুব বেশি তদন্তের জন্য না রাখা হয় তবে কিছু সমাধানও সেইসাথে সম্পাদন করতে পারে না
matsjoyce

6

পিএইচপি, দিকনির্দেশক পরীক্ষক, 203 213 216 229 231 এবং 229 233 জন পাস করে

এর অক্ষরগুলি সমস্ত ইনপুটটিতে উপস্থিত রয়েছে এমন শব্দের একটি তালিকা পাওয়ার জন্য অভিধানের মাধ্যমে একটি সহজ পাস দিয়ে শুরু হয় (মার্টিন এখানে কী করেছিল ), এবং কেবল কখন নকল হয় l.*তার পরিবর্তে পরীক্ষা করে ।l.*l.*l

এখানে দীর্ঘতম শব্দটি একটি ভেরিয়েবলে সংরক্ষণ করা হয়।

তারপরে আরও একটি চেক করা হবে, সেই পয়েন্টগুলির কীগুলির উপর ভিত্তি করে যেখানে সোয়াইপ দিক পরিবর্তন করে (+ / 0 থেকে - বা - / 0 থেকে +, এক্স বা y উভয় ক্ষেত্রে)। সম্ভাব্য শব্দের তালিকা অক্ষরের এই তালিকার বিপরীতে চেক করা হয়, এবং শব্দগুলি যা মেলে না তা মুছে ফেলা হয়। এই পদ্ধতির সঠিক হতে সোয়াইপিং মধ্যে তীক্ষ্ণ বাঁক উপর নির্ভর করে।

দীর্ঘতম বাকী শব্দটি আউটপুট করা হয়, বা কোনও শব্দ না থাকলে, আগের থেকে দীর্ঘতম শব্দটির পরিবর্তে আউটপুট হয়।

সম্পাদনা: সমস্ত অক্ষরকে একটি অনুভূমিক রেখায় যুক্ত করা হয়েছে যা চেক করার জন্য সম্ভাব্য মানের হিসাবে দিক পরিবর্তন করতে পারে।

পিএইচপি 5.4 প্রয়োজনীয় (বা এর [..]সাথে সমস্ত প্রতিস্থাপন array(..))।

<?php
function get_dir($a, $b){
    $c = [0, 0];
    if($a[0] - $b[0] < -1.4) $c[0] = 1;
    else if($a[0] - $b[0] > 1.4) $c[0] = -1;
    if($a[1] < $b[1]) $c[1] = 1;
    else if($a[1] > $b[1]) $c[1] = -1;
    return $c;
}
function load_dict(){
    return explode(PHP_EOL, file_get_contents('wordlist'));
}

$coord = [];
$f = fopen('keypos.csv', 'r');
while(fscanf($f, "%c, %f, %f", $c, $x, $y)){
    $coord[$c] = [$x, $y];  
}
fclose($f);

$dict = load_dict();
$in = $argv[1];
$possib = [];

foreach($dict as $c){
    if($c[0] == $in[0]){
        $q = strlen($c);
        $r = strlen($in);
        $last = '';
        $fail = false;
        $i = $j = 0;
        for($i = 0; $i < $q; ++$i){
            if($last == $c[$i]) continue;
            if($j >= $r){
                $fail = true;
                break;
            }
            while($c[$i] != $in[$j++])
                if($j >= $r){
                    $fail = true; 
                    break;
                }
            if($fail) break;
            $last = $c[$i];
        }
        if(!$fail) 
            $possib[] = $c;
    }
}

$longest = '';
foreach($possib as $p){
    if(strlen($p) > strlen($longest))
        $longest = $p;
}

$dir = [[0, 0]];
$cdir = [0, 0];
$check = '/^' . $in[0] . '.*?';
$olst = []; $p = 1;

$len = strlen($in);
for($i = 1; $i < $len; ++$i){
    $dir[$i] = get_dir($coord[$in[$i - 1]], $coord[$in[$i]]);
    $olddir = $cdir;
    $newdir = $dir[$i];
    $xc = $olddir[0] && $newdir[0] && $newdir[0] != $olddir[0];
    $yc = $olddir[1] && $newdir[1] && $newdir[1] != $olddir[1];
    if($xc || $yc){ // separate dir from current dir
        if($yc && !$xc && $dir[$i - 1][1] == 0){
            $tmp = '';
            for($j = $i - 1; $j >= 0 && $dir[$j][1] == 0; --$j){
                $tmp = '(' . $in[$j-1] . '.*?)?' . $tmp;
            }
            $olst[] = range($p, $p + (($i - 1) - $j));
            $p += ($i - 1) - $j + 1;
            $check .= $tmp . '(' . $in[$i - 1] . '.*?)?';
        }else{
            $check .= $in[$i - 1] . '.*?';
        }
        $cdir = $dir[$i];
    }else{
        if(!$cdir[0]) $cdir[0] = $dir[$i][0]; 
        if(!$cdir[1]) $cdir[1] = $dir[$i][1]; 
    }
}
$check .= substr($in, -1) . '$/';
$olstc = count($olst);
$res = [];
foreach($possib as $p){
    if(preg_match($check, $p, $match)){
        if($olstc){
            $chk = array_fill(0, $olstc, 0);
            for($i = 0; $i < $olstc; ++$i){
                foreach($olst[$i] as $j){
                    if(isset($match[$j]) && $match[$j]){
                        ++$chk[$i];
                    }
                }
                // give extra weight to the last element of a horizontal run
                if(@$match[$olst[$i][count($olst[$i])-1]])
                    $chk[$i] += 0.5;
            }
            if(!in_array(0, $chk)){
                $res[$p] = array_sum($chk);
            }
        }else{
            $res[$p] = 1;
        }
    }
}
$possib = array_keys($res, @max($res));
$newlong = '';
foreach($possib as $p){
    if(strlen($p) > strlen($newlong))
        $newlong = $p;
}
if(strlen($newlong) == 0) echo $longest;
else echo $newlong;

প্রশ্নগুলি পড়ার সময় @matjoyce এই বুলেট পয়েন্টটি মিস করেছেন। কোড এখন অবস্থানগুলি ব্যবহার করেkeypos.csv
es1024

@ es1024 যদিও 250 টি পরীক্ষার মামলার অংশ নয়, শব্দ তালিকায় টানা তিনটি অক্ষর সহ 238 টি শব্দ রয়েছে (এখন পর্যন্ত, আমি যাচাই করেছি সমস্ত শব্দই শেষ হওয়া শব্দগুলি sss) - আমি মনে করি না যে আপনার সদৃশ অপসারণগুলি সেগুলি ধরা পড়ে।
মার্টিন ইন্ডার

আপনার যদি এটির প্রয়োজন হয়, github.com/matjoyce/codegolf-swipe-type/blob/master/logs/…
matsjoyce

3

পাইথন 3, কর্নার সিমুলেটর, 241 এবং 240 পাস করেছে

অ্যালগরিদম:

  • প্রতিলিপি (একই চরিত্রের একটানা রান সরিয়ে ফেলুন) ইনপুট এবং শব্দের তালিকার সমস্ত শব্দ (মূল শব্দ ফিরে পাওয়ার জন্য অভিধান ব্যবহার করে)
  • সোয়াইপের শুরু এবং শেষের সাথে শুরু হওয়া এবং শেষ না হওয়া সমস্ত শব্দ সরিয়ে ফেলুন (প্রথম পাস)
  • 80 ডিগ্রির চেয়ে বেশি কোণে একটি রেজেক্স তৈরি করুন, তারপরে এই (দ্বিতীয় পাস) এর সাথে মেলে না এমন সমস্ত শব্দ সরিয়ে ফেলুন
  • সোয়াইপের বিপরীতে প্রতিটি শব্দের (রিজেক্স সলভারের মতো) পুনরায় ভাগ করুন, তারপরে সোয়াইপকে তাত্ত্বিকভাবে সরল রেখার একটি সিরিজে বিভক্ত করুন এবং সেগুলি সরল কিনা তা পরীক্ষা করে দেখুন ( significant_letterফাংশন) (তৃতীয় পাস)
  • সরলরেখার নিকটবর্তী হয়ে শব্দগুলি বাছাই করুন
  • তারপরে টাই ব্রেকার হিসাবে দৈর্ঘ্যটি ব্যবহার করুন (আরও ভাল)
  • তারপরে চূড়ান্ত টাই ব্রেকার হিসাবে লেভেনস্টেইন দূরত্ব ব্যবহার করুন
  • আউটপুট শব্দ!

কোড:

# Corner Sim

from math import atan, degrees, pi, factorial, cos, radians
import csv
import re
import sys

keys = {}
key_size = 1.5
for line in open("keypos.csv"):
    k, x, y = map(str.strip, line.split(","))
    keys[k] = float(x), float(y)


def deduplicate(s):
    return s[0] + "".join(s[i + 1] for i in range(len(s) - 1) if s[i + 1] != s[i])


def angle(coord1, coord2):
    x1, y1, x2, y2 = coord1 + coord2
    dx, dy = x2 - x1, y1 - y2
    t = abs(atan(dx/dy)) if dy else pi / 2
    if dx >= 0 and dy >= 0: a = t
    elif dx >= 0 and dy < 0: a = pi - t
    elif dx < 0 and dy >= 0: a = 2 * pi - t
    else: a = t + pi
    return degrees(a)


def significant_letter(swipe):
    if len(swipe) <= 2: return 0
    x1, y1, x2, y2 = keys[swipe[0]] + keys[swipe[-1]]
    m = 0 if x2 == x1 else (y2 - y1) / (x2 - x1)
    y = lambda x: m * (x - x1) + y1
    def sim_fun(x2, y2):
        try: return (x2 / m + y2 - y1 + x1 * m) / (m + 1 / m)
        except ZeroDivisionError: return x2
    dists = []
    for i, key in enumerate(swipe[1:-1]):
        sx, bx = min(x1, x2), max(x1, x2)
        pos_x = max(min(sim_fun(*keys[key]), bx), sx)
        sy, by = min(y1, y2), max(y1, y2)
        pos_y = max(min(y(pos_x), by), sy)
        keyx, keyy = keys[key]
        dist = ((keyx - pos_x) ** 2 + (keyy - pos_y) ** 2) ** 0.5
        a = angle((keyx, keyy), (pos_x, pos_y))
        if 90 <= a <= 180: a = 180 - a
        elif 180 <= a <= 270: a = a - 180
        elif 270 <= a <= 360: a = 360 - a
        if a > 45: a = 90 - a
        h = key_size / 2 / cos(radians(a))
        dists.append((max(dist - h, 0), i + 1, key))
    return sorted(dists, reverse=True)[0][0]


def closeness2(s, t):
    # https://en.wikipedia.org/wiki/Levenshtein_distance
    if s == t: return 0
    if not len(s): return len(t)
    if not len(t): return len(s)
    v0 = list(range(len(t) + 1))
    v1 = list(range(len(t) + 1))
    for i in range(len(s)):
        v1[0] = i + 1
        for j in range(len(t)):
            cost = 0 if s[i] == t[j] else 1
            v1[j + 1] = min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost)
        for j in range(len(v0)):
            v0[j] = v1[j]
    return v1[len(t)] / len(t)


def possible(swipe, w, s=False):
    m = re.match("^" + "(.*)".join("({})".format(i) for i in w) + "$", swipe)
    if not m or s:
        return bool(m)
    return closeness1(swipe, w) < 0.8


def closeness1(swipe, w):
    m = re.match("^" + "(.*)".join("({})".format(i) for i in w) + "$", swipe)
    unsigpatches = []
    groups = m.groups()
    for i in range(1, len(groups), 2):
        unsigpatches.append(groups[i - 1] + groups[i] + groups[i + 1])
    if debug: print(unsigpatches)
    sig = max(map(significant_letter, unsigpatches))
    if debug: print(sig)
    return sig


def find_closest(swipes):
    level1, level2, level3, level4 = swipes
    if debug: print("Loading words...")
    words = {deduplicate(i.lower()): i.lower() for i in open("wordlist").read().split("\n") if i[0] == level1[0] and i[-1] == level1[-1]}
    if debug: print("Done first filter (start and end):", words)
    r = re.compile("^" + ".*".join(level4) + "$")
    pos_words2 = list(filter(lambda x: bool(r.match(x)), words))
    if debug: print("Done second filter (sharpest points):", pos_words2)
    pos_words = pos_words2 or words
    pos_words = list(filter(lambda x: possible(level1, x), pos_words)) or list(filter(lambda x: possible(level1, x, s=True), pos_words))
    if debug: print("Done third filter (word regex):", pos_words)
    sorted_pos_words = sorted((closeness1(level1, x), -len(x), closeness2(level1, x), x)
                              for x in pos_words)
    if debug: print("Closeness matching (to", level2 + "):", sorted_pos_words)
    return words[sorted_pos_words[0][3]]


def get_corners(swipe):
    corners = [[swipe[0]] for i in range(4)]
    last_dir = last_char = None
    for i in range(len(swipe) - 1):
        dir = angle(keys[swipe[i]], keys[swipe[i + 1]])
        if last_dir is not None:
            d = abs(last_dir - dir)
            a_diff = min(360 - d, d)
            corners[0].append(last_char)
            if debug: print(swipe[i], dir, last_dir, a_diff, end=" ")
            if a_diff >= 55:
                if debug: print("C", end=" ")
                corners[1].append(last_char)
            if a_diff >= 65:
                if debug: print("M", end=" ")
                corners[2].append(last_char)
            if a_diff >= 80:
                if debug: print("S", end=" ")
                corners[3].append(last_char)
            if debug: print()
        last_dir, last_char = dir, swipe[i + 1]
    tostr = lambda x: deduplicate("".join(x + [swipe[-1]]).lower())
    return list(map(tostr, corners))


if __name__ == "__main__":
    debug = "-d" in sys.argv
    if debug: sys.argv.remove("-d")
    swipe = deduplicate(sys.argv[1] if len(sys.argv) > 1 else input()).lower()
    corners = get_corners(swipe)
    if debug: print(corners)
    print(find_closest(corners))

সাথে চালাও python3 entries/corner_sim.py


এটি একটি বৈধ উত্তর ছিল। আমার উত্তর দেওয়ার দরকার নেই।
অপটিমাইজার

@ অপ্টিমাইজার ওয়েল, মেটা আলোচনাটি আপনার উত্তরটি গ্রহণ করার পক্ষে বলে মনে হচ্ছে, তাই আমার পক্ষে এটি সূক্ষ্ম।
matsjoyce

কেবল সেই মেটা আলোচনার পরে, আপনার সিদ্ধান্ত নিয়ে আমি ঠিক ছিলাম, তবে এটিও ভাল (আরও ভাল) :)
অপটিমাইজার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.