সর্বোত্তম সংক্ষিপ্ত হাতে রোমান অঙ্কের জেনারেটর


21

লক্ষ্য:
এমন একটি ফাংশন লিখুন যা কোনও সংখ্যাকে ইনপুট হিসাবে নেয় এবং আউটপুট হিসাবে সেই সংখ্যার জন্য একটি সংক্ষিপ্ত হাতের রোম্যান অঙ্ক দেয়।

রোমান সংখ্যা চিহ্ন:

Symbol  Value
I       1
V       5
X       10
L       50
C       100
D       500
M       1,000

আমি যখন "সংক্ষিপ্ত হাতের রোমান সংখ্যক" বলি তখন তার অর্থের উদাহরণের জন্য, 1983 উপস্থাপনের জন্য রোমান অঙ্কটি সন্ধান করা বিবেচনা করি, কারণ এটিই আমার জন্ম হয়েছিল year একটি বিকল্প হ'ল এটি সাধারণ পদ্ধতিতে (10 টি বর্ণ):

1983 = এমসিএমএলএক্সএক্সএক্সআইআইআই = (1000 - 100 + 1000 + 50 + 30 + 3)

অন্য বিকল্পটি হ'ল এটি স্বল্প হাতের উপায়ে করা (6 টি অক্ষর):

1983 = এমএক্সভিআইআইএম = (1000 - (10 + 10) + 1000 + 3)

আপনি কি জানেন এর মানে কি?!?!!?? আমি রোমান হলে আমি প্রতিবার আমার জন্ম তারিখটি লিখতে পারলে 4 টি অক্ষর বাঁচাতে পারতাম! ওয়াট ওয়াট !!

যাইহোক, উত্তেজনায় আমি নিজের থেকে এগিয়ে যাওয়ার আগে, আমার লেখার একটি প্রশ্ন রয়েছে, তাই আমার সম্ভবত শর্ট-হ্যান্ড রোমান সংখ্যার নিয়মটি সংজ্ঞায়িত করা উচিত তাই আমরা সবাই একই পৃষ্ঠায় রয়েছি:

স্বল্প হাতে রোমান সংখ্যার নিয়ম:

  1. বিবেচনা করার মতো আর কোনও অক্ষর না পাওয়া পর্যন্ত সর্বদা বাম থেকে ডানে প্রতীকগুলি বিবেচনা করুন।
  2. যদি বর্তমান প্রতীকটির ডানদিকে কোনও উচ্চ-মূল্যবান চিহ্ন থাকে না:
    • এই রোমান সংখ্যার চলমান মোটটিতে বর্তমান প্রতীকটির মান যুক্ত করুন।
  3. আপনি যে চিহ্নটি বিবেচনা করছেন তার ডানদিকে যদি উচ্চ-মূল্যবান চিহ্ন থাকে:
    • বর্তমান প্রতীকের ডানদিকে সর্বনিম্ন সর্বোচ্চ-মূল্যবান প্রতীকটি চিহ্নিত করুন
    • সেই প্রতীক পর্যন্ত সমস্ত অক্ষরকে একটি রোমান অঙ্ক হিসাবে বিবেচনা করুন
    • এই পদক্ষেপগুলি ব্যবহার করে সেই রোমান অঙ্কের মান গণনা করুন
    • এই রোমান অঙ্কের চলমান মোট থেকে সেই রোমান সংখ্যার মান বিয়োগ করুন।
    • আপনি সবেমাত্র বিবেচনা করেছেন সেই গোষ্ঠীর পরে পরবর্তী প্রতীকটিতে যান to
  4. প্রতিটি রোমান অঙ্কের অবশ্যই এতে কমপক্ষে 1 টি চিহ্ন থাকতে হবে।
  5. এটাই! এই নিয়ম অনুসরণ করে যে কোনও কিছু গ্রহণ করা হবে!

উদাহরণ:

IIIIV = (-(1+1+1+1)+5) = 1  //Don't ask me why you'd want to do this!  

VVX = (-(5+5) + 10) = 0  //Who said you couldn't represent 0 with roman numerals?!!?

VVXM = (-(-(5+5) + 10) + 1000) = 1000  //Again...don't ask me why you'd want to do this!

MXIIXMI = (1000-(10-(1+1)+10)+1000+1) = 1983  //Ahhh...such a great year :)

প্রশ্ন বিধি:

  1. একটি ফাংশন তৈরি করুন যা ইনপুট হিসাবে একক সংখ্যা নেয় এবং উপরের নিয়মগুলি ব্যবহার করে আউটপুট হিসাবে সেই সংখ্যার জন্য রোমান অঙ্কটি প্রদান করে। এই ফাংশনের কোড গল্ফস্কোর গণনা করুন ।

    example input: 2011
    example possible output: MMXI
    another possible output: MMVVIVV     //(2000 + 10 - 4 + 5) 
    
  2. নিয়ম 1 থেকে আপনার ফাংশনটি ব্যবহার করে, -1000 (এটি সঠিক, নেজিটিভ এক-হাজার) এবং 3000 এর মধ্যে রোমান অঙ্কগুলি তৈরি করুন Then তারপরে আপনার মোটক্যারাক্টরকাউন্ট পেতে এই রোমান সংখ্যার চরিত্রের দৈর্ঘ্য যোগ করুন । এখানে স্পষ্ট করার জন্য কয়েকটি সিউডোকোড:

    totalCharacterCount = 0;
    for(currentNumber = -1000; currentNumber <= 3000; currentNumber++){
        totalCharacterCount += getRomanNumeral(currentNumber).length;
    }
    return totalCharacterCount;
    
  3. ফাইনালস্কোর = কোডগলফস্কোর + মোটচক্র্যাক্টর उंट ount

  4. সর্বনিম্ন ফাইনাল স্কোর জয়!

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

শুভকামনা, এবং আগামীকাল রাতে আপনার এমএমএক্সআইআই উদযাপনে মজা করুন !!!


1
দুর্দান্ত কাজ! তবে, আপনি কীভাবে নেতিবাচক রোমান শর্টহ্যান্ডের মতো দেখায় তার উদাহরণ দিতে পারেন? DDDDMদাঁড়ানো কি -1000?
pimvdb

@Pimvdb আপনি এটি পেয়েছেন!
ব্রিগেয় 37

বিশেষ ক্ষেত্রে শূন্য সম্পর্কিত একটি প্রশ্ন: ""শূন্যের জন্য অনুমোদিত কি আমাদের ব্যবহার করতে হবে VVXবা সমমানের কিছু?
হাওয়ার্ড

@ হাওয়ার্ড: দুর্দান্ত প্রশ্ন, আমি এটি ভেবে দেখিনি! আমি রোমান সংখ্যার নিয়ম 4 যুক্ত করেছি যার জন্য সেই মামলাটি স্পষ্ট করে।
ব্রিগ্যুই 37

1
"বর্তমান প্রতীকটির ডানদিকে সবচেয়ে সর্বাধিক মূল্যবান প্রতীকটি চিহ্নিত করুন" - কোনটি জিতবে, ডানদিকের বা সর্বোচ্চ-মূল্যবান? অর্থাত্, IXV = -(-1 + 10) + 5 = -4(ডানদিকের জয়), বা IXV = -1 + 10 + 5 = 14(সর্বোচ্চ মূল্যবান জয়)?
কিথ র্যান্ডাল 21

উত্তর:


5

হাস্কেল, 25637 (= 268 + 25369) 26045 (= 222 + 25823)

r 0="VVX"
r n=s(zip[1000,500,100,50,10,5]"MDCLXV")n ξ
ξ='ξ'
s[]q f
 |q<0=s[](5-q)f++"V"
 |q<1=""
 |r<-q-1='I':s[]r f
s ω@((v,a):l)q f
 |q>=v,f/=a=a:s ω(q-v)ξ
 |f==a,γ<-'I':a:s l(q-v+1)ξ,η γ<η(s l q ξ)=γ
 |f==ξ,γ<-s ω(v-q)a++[a],η γ<η(s l q ξ)=γ
 |True=s l q ξ
η=length

যেমন ব্যবহার করা

GHCi> r 7
"VII"
GHCi> r 39
"XIL"
GHCi> r (-39)
"ICXLC"        --  "LLXILC" in my original version
GHCi> r 1983
"MXVIIM"
GHCi> r 259876
"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCXXIVM"

আপনি সোজা নিয়ে দৈর্ঘ্যের সমষ্টিটি মূল্যায়ন করতে পারেন

GHCi> sum . map(length.r) $ [-1000..3000]
25369

যা এক মিনিটের ক্রমে কিছু নেয়।


5

সি ++, কোডের 345 টি অক্ষর, 25021 রোমান অঙ্কগুলি = 25366

int N[]={1,5,10,50,100,500,1000};int V(int s,int L){if(!L)return 0;int K=0,B,m=s%7+1;for(int k=1,b=7;k<L;k++,b*=7){if(s/b%7>=m){K=k;B=b;m=s/b%7;}}return K?V(s/B,L-K)-V(s%B,K):N[s%7]+V(s/7,L-1);}char r[99];char*f(int n){for(int L=1,B=7,i,j;1;L++,B*=7){for(i=0;i<B;i++){if(V(i,L)==n){for(j=0;j<L;j++){r[j]="IVXLCDM"[i%7];i/=7;}r[L]=0;return r;}}}}

ড্রাইভার সহ কিছুটা ডিওবাফাসেকেটেড:

int N[]={1,5,10,50,100,500,1000};
int V(int s,int L){
  if(!L)return 0;
  int K=0,B,m=s%7+1;
  for (int k=1,b=7;k<L;k++,b*=7) {
    if(s/b%7>=m){K=k;B=b;m=s/b%7;}
  }
  return K ? V(s/B,L-K)-V(s%B,K) : N[s%7]+V(s/7,L-1);
}
char r[99];
char *f(int n){
  for(int L=1,B=7;1;L++,B*=7) {
    for(int i=0;i<B;i++) {
      if(V(i,L)==n){
        for(int j=0;j<L;j++) {
          r[j]="IVXLCDM"[i%7];i/=7;
        }
        r[L]=0;
        return r;
      }
    }
  }
}
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
  printf("%s\n", f(atoi(argv[1])));
}

Vপ্রদত্ত রোমান অঙ্কের sদৈর্ঘ্যের সংখ্যার মানকে গণনা করে L। স্ট্রিংগুলি বেস 7 টি এনকোড করা হয় (প্রথম সংখ্যাটি s% 7, দ্বিতীয় সংখ্যা s / 7% 7, ...)। প্রতিটি অঙ্ক I = 0, V = 1, ..., M = 6 দিয়ে এনকোড করা থাকে। মূল্যায়ন করে এমন fকোনও সন্ধানের জন্য সম্ভাব্য রোমান অঙ্কের স্ট্রিংগুলির একটি নিষ্ঠুর-শক্তি গণনা Vকরে n

রোমান সংখ্যার মোট সংখ্যাটি সর্বোত্তম is [-1000,3000] এর জন্য সবচেয়ে দীর্ঘতম রোমান সংখ্যার 11 সংখ্যা (যেমন -827 = CMDDMLXXIII), যা আমার মেশিনে প্রায় 5 মিনিট সময় নেয়।


একটি মুহুর্ত অপেক্ষা করুন, এটি নির্দিষ্টভাবে আচরণ করে না। আপনার প্রোগ্রাম যেমন LMCLXXIIIউত্তর হিসাবে উদাহরণ দেয় -777। আমি এটি " সর্বাধিক " পরিবর্তে " সর্বাধিক উচ্চমানের-50+1000-100+50+10+10+3 = 923 ≠ -777 " দিয়ে পড়ি তবে এটিই দেয় । আপনি মন্তব্যগুলিতে যা চেয়েছিলেন তা ঠিক তাই! -777
বন্ধ হয়ে গেছে

@ বামফ্রন্টাবাউট: অবশ্যই আপনি ঠিক বলেছেন। আমি এটি ঠিক করে দেব, তবে এখনই কোন সময় নেই ...
কীথ র্যান্ডাল

@ বামফ্রন্টাবাউট: ঠিক আছে, সব ঠিক আছে।
কিথ র্যান্ডাল

ঠিক আছে. এটা না অনুকূল এখন, যদিও (যেমন দেয় VVVXIজন্য -4যখন IXVXআসলে খাটো, যেমন আমি শুধু খেয়াল) - কিন্তু যে পুরোপুরি বৈধতা পাবে।
ঘড়ির

@ বামফ্রন্টাবাউট: ঠিক আছে, আবার ঠিক হয়েছে। আশা রাখি, এই সময় সঠিক হয় ...
কিথ রান্ডাল

2

রুবি, 25987 (= 164 + 25823)

h=->i,d,v,k{i==0?'':i<v ?(a=h[v-i,x=d[1..-1],v/k,k^7]+d[0];i<0?a:(b=h[i,x,v/k,k^7];a.size<b.size ? a :b)):d[0]+h[i-v,d,v,k]}
r=->i{i==0?'DDM':h[i,'MDCLXVI',1000,2]}

rফলাফল পেতে আপনি সরাসরি কল করতে পারেন । নির্দিষ্ট ব্যাপ্তির ফলনের উপর যোগফল

> (-1000..3000).map{|i|r[i].size}.reduce &:+
25823

যা অন্যান্য সমাধানগুলির সাথে সর্বোত্তম যোগফল।


0

সি # 23537 (কোডের 638৯ টি অক্ষর + আউটপুটের 22898 টি অক্ষর)

class M
{
    public static string R(int n, int? s = new int?())
    {
        var r = "";
        var D = new Dictionary<int, string> {{ 1000, "M"}, { 900, "CM"},{ 800, "CCM"},{ 500, "D"}, { 400, "CD"},{ 300, "CCD"},{100, "C"}, {90, "XC"},{80, "XXC"},{50, "L"}, {40, "XL"}, {10, "X"}, {9, "IX"}, {8, "IIX"}, {5, "V"}, {4, "IV"},{1, "I"}};
        if (n == 0) return "VVX";
        if (n == -1) return "IIIIIIV";
        if (n < 0) return N(n * -1);

        foreach(int k in D.Keys)
        {
            if (s.HasValue && k > s) continue;

            while(k <= n)
            {
                n -= k; 
                r += D[k];
            }
        }

        return r;
    }

    public static string N(int n)
    {
        var D = new Dictionary<int, string> {{1, "I"}, {5, "V"}, {10, "X"}, {50, "L"}, {100, "C"}, { 500, "D"}, {1000, "M"}};

        int i = D.Keys.First(v => v >= n), m = D.Keys.Where(v => v < i).Max();

        return R(n + i, m) + D[i];
    }
}

হিসাব করতে:

Enumerable.Range(-1000, 3000).Sum(i => M.R(i).Length);


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