অনেক 'যদি' বিবৃতি?


263

নিম্নলিখিত কোডটি আমার কীভাবে এটি প্রয়োজন তা কাজ করে তবে এটি কুরুচিপূর্ণ, অতিরিক্ত বা অন্যান্য কিছু বিষয়। আমি সূত্রগুলি দেখেছি এবং কয়েকটি সমাধান লেখার চেষ্টা করেছি, তবে আমি সমান পরিমাণ বিবৃতি দিয়ে শেষ করছি।

গণিতের এমন কোনও সূত্র আছে যা আমাকে এই পরিস্থিতিতে উপকৃত করতে পারে বা বিবৃতি গ্রহণযোগ্য হলে 16 টি?

কোডটি ব্যাখ্যা করার জন্য, এটি এক ধরণের যুগপত-টার্ন-ভিত্তিক গেমের জন্য .. দু'জন খেলোয়াড়ের প্রত্যেকটিতে চারটি অ্যাকশন বোতাম থাকে এবং ফলাফলগুলি অ্যারের (0-3) থেকে আসে তবে 'এক' এবং 'দুটি' পরিবর্তনশীল হতে পারে এই সাহায্য করে যদি কিছু বরাদ্দ। ফলাফল, 0 = না হয় জয়, 1 = পি 1 জয়, 2 = পি 2 জয়, 3 = উভয়ই জয়।

public int fightMath(int one, int two) {

    if(one == 0 && two == 0) { result = 0; }
    else if(one == 0 && two == 1) { result = 0; }
    else if(one == 0 && two == 2) { result = 1; }
    else if(one == 0 && two == 3) { result = 2; }
    else if(one == 1 && two == 0) { result = 0; }
    else if(one == 1 && two == 1) { result = 0; }
    else if(one == 1 && two == 2) { result = 2; }
    else if(one == 1 && two == 3) { result = 1; }
    else if(one == 2 && two == 0) { result = 2; }
    else if(one == 2 && two == 1) { result = 1; }
    else if(one == 2 && two == 2) { result = 3; }
    else if(one == 2 && two == 3) { result = 3; }
    else if(one == 3 && two == 0) { result = 1; }
    else if(one == 3 && two == 1) { result = 2; }
    else if(one == 3 && two == 2) { result = 3; }
    else if(one == 3 && two == 3) { result = 3; }

    return result;
}


9
নিশ্চয়ই এখানে কিছু যুক্তি রয়েছে যা জোর করে চাপিয়ে দেওয়ার পরিবর্তে সাধারণীকরণ করা যায়? অবশ্যই কিছু ফাংশন f(a, b)আছে যা সাধারণ ক্ষেত্রে উত্তর দেয়? আপনি গণনার যুক্তি ব্যাখ্যা করেন নি তাই সমস্ত উত্তরগুলি কেবল শূকরের লিপস্টিক। আমি intক্রিয়াকলাপের জন্য পতাকা ব্যবহার করা খুব পুরানো program enumগুলি যুক্তিযুক্ত থাকতে পারে এবং বর্ণনামূলক হতে পারে, এটি আপনাকে আরও আধুনিক পদ্ধতিতে আপনার কোডটি লেখার অনুমতি দেয়।
বোরিস স্পাইডার

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

9
আপনার যদি কোনও উত্তর থাকে তবে দয়া করে এটি পোস্ট করুন। মন্তব্যে বর্ধিত আলোচনা অনুসরণ করা শক্ত, বিশেষত কোড জড়িত থাকার সময়। আপনি যদি এই প্রশ্নটি কোড পর্যালোচনাতে স্থানান্তরিত করা উচিত ছিল কিনা সে সম্পর্কে কথা বলতে চান, সে সম্পর্কে একটি মেটা আলোচনা রয়েছে।
জর্জ স্টকার

1
"ডাটাবেসের মতো একই" বলতে কী বোঝ? এই মানগুলি ডাটাবেসে থাকলে সেগুলি সেখান থেকে টানুন। অন্যথায়, যদি এটি সত্যিই জটিল হয় তবে আমি এটি আপনার মতো করে রেখে দেব এবং প্রতিটি লাইনের পরে ব্যবসায়িক যুক্তি মন্তব্য যুক্ত করব যাতে লোকেরা বুঝতে পারে যে কী চলছে। এটি দীর্ঘ (সুস্পষ্ট) আমার কাছে আরও ভাল - ভবিষ্যতে কেউ কী বুঝতে পারে তা বুঝতে পারে। আপনি যদি এটি কোনও মানচিত্রে রাখেন বা 8 টি লাইন কোড সংরক্ষণের চেষ্টা করেন, তবে উলটো দিকটি সত্যিই ছোট এবং ডাউনসাইজটি আরও বড়: আপনি যদি একদিন আপনার কোড পড়তে চান তবে আপনি এটিকে আরও বেশি বিভ্রান্তিকর করে তুলছেন।
স্কাজ

উত্তর:


600

আপনি যদি কোনও সূত্র নিয়ে আসতে না পারেন, আপনি এই জাতীয় সীমিত সংখ্যক ফলাফলের জন্য একটি টেবিল ব্যবহার করতে পারেন:

final int[][] result = new int[][] {
  { 0, 0, 1, 2 },
  { 0, 0, 2, 1 },
  { 2, 1, 3, 3 },
  { 1, 2, 3, 3 }
};
return result[one][two];

7
এটি আকর্ষণীয় কারণ আমি এই সমাধানটি আগে দেখিনি seen আমি মোটামুটি নিশ্চিত নই যে আমি রিটার্নের ফলাফলটি বুঝতে পেরেছি তবে এটি পরীক্ষা করে উপভোগ করব।
টমফर्थ

4
আপনার IndexOutOfBoundsExceptionদৃ the়তার প্রয়োজন নেই, এক বা একাধিক সূচক সীমার বাইরে থাকলে জাভা যে কোনও উপায়ে নিক্ষেপ করবে ।
জ্যাব

43
@ জোহ্পার্পার যদি আপনি সহজে কিছু পড়তে চান তবে আপনি প্রথমে যাদু নম্বর ব্যবহার করবেন না এবং ম্যাপিংয়ের ব্যাখ্যা দেওয়ার জন্য আপনার একটি মন্তব্য থাকবে। যেমনটি হ'ল, আমি এই সংস্করণটিকে মূলটির তুলনায় পছন্দ করি তবে দীর্ঘমেয়াদে রক্ষণাবেক্ষণের জন্য আমি গণিত প্রকার বা কমপক্ষে নামকরণকৃত ধ্রুবকগুলির সাথে জড়িত একটি পদ্ধতির ব্যবহার করব।
জ্যাব

13
@ জোহার্পার "তাত্ত্বিকভাবে" একটি জিনিস, "ব্যবহারিকভাবে" আরেকটি জিনিস। অবশ্যই আমি বর্ণনামূলক নামকরণ ( লুপ ভেরিয়েবলের জন্য i/ j/ kকনভেনশন ব্যতীত) নামের ধ্রুবকগুলি, আমার কোডটি পাঠযোগ্য ফ্যাশনে সাজানো ইত্যাদি ব্যবহার করার চেষ্টা করি, তবে যখন ভেরিয়েবল এবং ফাংশনটির নাম 20 টিরও বেশি অক্ষর গ্রহণ শুরু করে প্রতিটি আমি এটি দেখতে পাই আসলে কম পাঠযোগ্য কোডের দিকে নিয়ে যায়। আমার স্বাভাবিক পদ্ধতির হ'ল কোডটি কেন এটির মতো কাঠামোগত করা হচ্ছে (বনাম কীভাবে) তা ব্যাখ্যা করার জন্য এখানে মন্তব্যগুলির সাথে বোধগম্য কিন্তু সংযোগ কোডের চেষ্টা করা। নামগুলিতে কেন রাখার ফলে সব কিছু ছড়িয়ে পড়ে।
জ্যাব

13
আমি এই নির্দিষ্ট সমস্যার জন্য এই সমাধানটি পছন্দ করি কারণ ফলাফলগুলি আসলে ফলাফল ম্যাট্রিক্স দ্বারা নির্ধারিত হয়।
চেষ্টা করা হচ্ছে

201

যেহেতু আপনার ডেটা সেটটি খুব ছোট, আপনি সবকিছুকে 1 দীর্ঘ পূর্ণসংখ্যায় সংকুচিত করতে এবং সূত্রে রূপান্তর করতে পারেন

public int fightMath(int one,int two)
{
   return (int)(0xF9F66090L >> (2*(one*4 + two)))%4;
}

আরও বিটভাইজ বৈকল্পিক:

এটি সত্যটি সমস্ত কিছু 2 এর একাধিক ব্যবহার করে

public int fightMath(int one,int two)
{
   return (0xF9F66090 >> ((one << 3) | (two << 1))) & 0x3;
}

ম্যাজিক কনস্ট্যান্টের উত্স

আমি কি বলতে পারি? বিশ্বের জাদু দরকার, কখনও কখনও কোনও কিছুর সম্ভাবনা তার সৃষ্টির জন্য ডাকে।

ওপির সমস্যা সমাধান করে এমন ফাংশনের সারমর্মটি হ'ল 2 নম্বর (এক, দুটি), ডোমেন {0,1,2,3 from থেকে {0,1,2,3 range পরিসীমা} উত্তরগুলির প্রত্যেকটি কীভাবে সেই মানচিত্রটি বাস্তবায়িত করতে পারে।

এছাড়াও, আপনি উত্তরগুলির একটি সংখ্যাটিতে দেখতে পাচ্ছেন 1 2-সংখ্যার বেস 4 নম্বর এন (এক, দুই) এর মানচিত্র হিসাবে সমস্যার পুনরুদ্ধার যেখানে এক সংখ্যা 1, দুটি হ'ল 2, এবং এন = 4 * এক + দুই; এন = {0,1,2, ..., 15} - ষোলটি ভিন্ন মান, এটি গুরুত্বপূর্ণ। ফাংশনের আউটপুটটি 1-অঙ্কের বেস 4 নম্বর {0,1,2,3} - 4 বিভিন্ন মান, এছাড়াও গুরুত্বপূর্ণ।

এখন, 1-সংখ্যার বেস 4 নম্বরটি 2-সংখ্যার বেস 2 নম্বর হিসাবে প্রকাশ করা যেতে পারে; {0,1,2,3} = {00,01,10,11}, এবং তাই প্রতিটি আউটপুট কেবল 2 বিট দিয়ে এনকোড করা যায়। উপরে থেকে, কেবলমাত্র 16 টি আলাদা আউটপুট সম্ভব, সুতরাং 16 * 2 = 32 বিটগুলি পুরো মানচিত্রকে এনকোড করার জন্য প্রয়োজনীয় সমস্ত কিছুই; এটি সমস্ত 1 পূর্ণসংখ্যার মধ্যে ফিট করতে পারে।

ধ্রুবক এম হ'ল ম্যাপের এনকোডিং যেখানে এম (0) বিটগুলিতে এনকোড করা হয়েছে [[0: 1], এম (1) বিটগুলিতে এনকোড করা হয়েছে এম [2: 3], এবং এম (এন) বিটগুলিতে এনকোড হয়েছে এম [n * যেসব 2: এন * 2 + 1 টি]।

যা যা অবশিষ্ট রয়েছে তা ধ্রুবকের ডান অংশটিকে সূচক এবং ফিরে দেওয়া, এক্ষেত্রে আপনি এম ডান 2 * এন বার স্থানান্তর করতে পারেন এবং 2 কমপক্ষে উল্লেখযোগ্য বিট নিতে পারেন, এটি হল (এম >> 2 * এন) এবং 0x3। এক্সপ্রেশন (এক << 3) এবং (দুটি << 1) 2 2 x x x << 1 এবং 8 * x = x << 3 নোট করার সময় কেবল জিনিসগুলি বাড়িয়ে দিচ্ছে।


79
স্মার্ট, তবে অন্য কেউ কোডটি পড়ার পক্ষে এটি বোঝার সুযোগ থাকবে না।
অরণ মুলহোল্যান্ড

106
আমি মনে করি এটি অত্যন্ত খারাপ অনুশীলন। লেখক ব্যতীত অন্য কেউ তা বুঝতে পারবে না। আপনি কোডের একটি অংশটি দেখতে এবং এটি দ্রুত বুঝতে চান want তবে এটি কেবল সময়ের অপচয়।
বালাজস নেমেথ

14
আমি এই নিয়ে @ বেলজসমারিয়া নেমেথের সাথে আছি। যদিও খুব চিত্তাকর্ষক, আপনার উচিত হিংসাত্মক সাইকোপ্যাথগুলির কোডিং!
OrhanC1

90
সমস্ত ডাউনভিটাররা মনে করে যে এটি একটি ঘৃণ্য কোড গন্ধ। সমস্ত upvoters একই চিন্তা করে, কিন্তু এর পিছনে চালাকতাকে প্রশংসা করে। +1 টি (কখনো এই কোড ব্যবহার করবেন না।)
usr ডিরেক্টরির

4
শুধু কোড লেখার কি সুন্দর উদাহরণ !
lealand

98

জাবের ব্যতীত উপস্থাপিত কোনও সমাধানই আমি পছন্দ করি না। অন্য কেউই কোডটি পড়তে এবং কী গণনা করা হচ্ছে তা বুঝতে সহজ করে না

এই কোডটি আমি কীভাবে লিখব তা এখানে - আমি কেবল জাভা নয়, সি # জানি but তবে আপনি ছবিটি পান:

const bool t = true;
const bool f = false;
static readonly bool[,] attackResult = {
    { f, f, t, f }, 
    { f, f, f, t },
    { f, t, t, t },
    { t, f, t, t }
};
[Flags] enum HitResult 
{ 
    Neither = 0,
    PlayerOne = 1,
    PlayerTwo = 2,
    Both = PlayerOne | PlayerTwo
}
static HitResult ResolveAttack(int one, int two)
{
    return 
        (attackResult[one, two] ? HitResult.PlayerOne : HitResult.Neither) | 
        (attackResult[two, one] ? HitResult.PlayerTwo : HitResult.Neither);
}    

এখন এখানে আরও কী পরিমাণ গণনা করা হচ্ছে তা আরও স্পষ্ট: এটি জোর দেয় যে আমরা কে কী আক্রমণে আক্রান্ত হয়ে গণনা করছি এবং উভয় ফলাফলই ফিরিয়ে দিচ্ছি।

তবে এটি আরও ভাল হতে পারে; যে বুলিয়ান অ্যারে কিছুটা অস্বচ্ছ। আমি টেবিল দেখার পদ্ধতির পছন্দ করি তবে আমি এটি এমনভাবে লিখতে আগ্রহী যা এটি স্পষ্ট করে দিয়েছিল যে গেমটির শব্দার্থিক উদ্দেশ্য কী। এটি হ'ল "শূন্যের আক্রমণ এবং কোনও ফলাফলের প্রতিরক্ষা কোনও ফলশ্রুতিতে আসে না" এর পরিবর্তে কোডটিকে আরও স্পষ্টভাবে বোঝানো যায় যে "লো কিক আক্রমণ এবং লো ব্লক প্রতিরক্ষা ফল হিট না" make কোডটি খেলাগুলির ব্যবসায়িক যুক্তিকে প্রতিবিম্বিত করুন।


66
আজেবাজে কথা. বেশিরভাগ হালকা অভিজ্ঞ প্রোগ্রামগুলি এখানে দেওয়া পরামর্শগুলির প্রশংসা করতে সক্ষম হবে এবং তাদের নিজস্ব ল্যাংগুলিতে কোডিং শৈলী প্রয়োগ করবে। প্রশ্নটি কীভাবে ifs এর স্ট্রিং এড়ানো যায় was এটি কিভাবে দেখায়।
গ্রিনএজজেড

6
@ ব্যবহারকারী 3414693: আমি জানি যে এটি একটি জাভা প্রশ্ন। উত্তরটি মনোযোগ সহকারে পড়লে তা পরিষ্কার হয়ে যায়। আপনি যদি বিশ্বাস করেন যে আমার উত্তরটি বুদ্ধিমানের নয় তবে আমি আপনাকে নিজের উত্তরটি লিখতে উত্সাহিত করব যা আপনার চেয়ে ভাল।
এরিক লিপার্ট

1
@ এরিকলিপার্ট আমি জ্যাবির সমাধানও পছন্দ করি। আইএমএইচএও, এন # টাইপ সি # তে অনেকগুলি পাতা পছন্দসই হতে পারে। এটি সাফল্যের দর্শনের গর্তটিকে অনুসরণ করে না যা অন্যান্য বৈশিষ্ট্যগুলি করে। উদাহরণস্বরূপ স্ট্যাকওভারফ্লো.com/ a/ 847353/92414 সি # টিমের আরও ভাল ডিজাইন করা কোন এনাম টাইপ (যাতে বিদ্যমান কোডটি ভঙ্গ করা এড়াতে পারে) তৈরি করার কোনও পরিকল্পনা আছে?
সলিউশন

@ সমাধানযোগি: আমি সি # তে এনামগুলিকে খুব বেশি পছন্দ করি না, যদিও তারা ভাল historicalতিহাসিক কারণে এগুলি করে। (বেশিরভাগ ক্ষেত্রে বিদ্যমান সিওএম এনামগুলির সাথে সামঞ্জস্যের জন্য C) আমি সি # 6 এ এনামগুলির জন্য নতুন গিয়ার যুক্ত করার কোনও পরিকল্পনা সম্পর্কে অবগত নই
এরিক লিপার্ট

3
@ এসলিস্ট নং, মন্তব্যগুলি চলবে না। ওপি ঠিক কী করণীয় তা করেছে; মন্তব্যগুলি সাফ কোডে রূপান্তর করুন। উদাহরণস্বরূপ দেখুন স্টিভ ম্যাককনেল কোড সম্পূর্ণ স্টিভমকনেল.com
cccntnt.htm

87

আপনি ম্যাট্রিক্স তৈরি করতে পারেন যার ফলাফল রয়েছে

int[][] results = {{0, 0, 1, 2}, {0, 0, 2, 1},{2, 1, 3, 3},{2, 1, 3, 3}};

আপনি যখন মান পেতে চান তখন আপনি ব্যবহার করবেন

public int fightMath(int one, int two) {
  return this.results[one][two]; 
}

69

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

public int fightMath(int one, int two) {
    if (one > 3 || one < 0 || two > 3 || two < 0) {
        throw new IllegalArgumentException("Result is undefined for arguments outside the range [0, 3]");
    }

    if (one <= 1) {
        if (two <= 1) return 0;
        if (two - one == 2) return 1;
        return 2; // two can only be 3 here, no need for an explicit conditional
    }

    // one >= 2
    if (two >= 2) return 3;
    if (two == 1) return 1;
    return 2; // two can only be 0 here
}

এটি অন্যথায় ইনপুট-> ফলাফল ম্যাপিংয়ের অংশগুলির অনিয়মের কারণে হতে পারে এর চেয়ে কম পাঠযোগ্য হতে পারে up আমি ম্যাট্রিক্স শৈলীর পরিবর্তে এর সরলতার কারণে এবং কীভাবে আপনি ম্যাট্রিক্সটি দৃষ্টিভঙ্গি করে তুলতে পারেন (যদিও এটি কর্নো ম্যাপের আমার স্মৃতি দ্বারা প্রভাবিত):

int[][] results = {{0, 0, 1, 2},
                   {0, 0, 2, 1},
                   {2, 1, 3, 3},
                   {2, 1, 3, 3}};

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

enum MoveType {
    ATTACK,
    BLOCK;
}

enum MoveHeight {
    HIGH,
    LOW;
}

enum Move {
    // Enum members can have properties/attributes/data members of their own
    ATTACK_HIGH(MoveType.ATTACK, MoveHeight.HIGH),
    ATTACK_LOW(MoveType.ATTACK, MoveHeight.LOW),
    BLOCK_HIGH(MoveType.BLOCK, MoveHeight.HIGH),
    BLOCK_LOW(MoveType.BLOCK, MoveHeight.LOW);

    public final MoveType type;
    public final MoveHeight height;

    private Move(MoveType type, MoveHeight height) {
        this.type = type;
        this.height = height;
    }

    /** Makes the attack checks later on simpler. */
    public boolean isAttack() {
        return this.type == MoveType.ATTACK;
    }
}

enum LandedHit {
    NEITHER,
    PLAYER_ONE,
    PLAYER_TWO,
    BOTH;
}

LandedHit fightMath(Move one, Move two) {
    // One is an attack, the other is a block
    if (one.type != two.type) {
        // attack at some height gets blocked by block at same height
        if (one.height == two.height) return LandedHit.NEITHER;

        // Either player 1 attacked or player 2 attacked; whoever did
        // lands a hit
        if (one.isAttack()) return LandedHit.PLAYER_ONE;
        return LandedHit.PLAYER_TWO;
    }

    // both attack
    if (one.isAttack()) return LandedHit.BOTH;

    // both block
    return LandedHit.NEITHER;
}

এমনকি যদি আপনি আরও উচ্চতার ব্লক / আক্রমণ যোগ করতে চান তবে আপনাকে নিজেই ফাংশনটি পরিবর্তন করতে হবে না; অতিরিক্ত ধরণের পদক্ষেপ যুক্ত করার জন্য সম্ভবত ফাংশনটির পরিবর্তন প্রয়োজন হবে require এছাড়াও মূল এনামের বৈশিষ্ট্য হিসাবে অতিরিক্ত এনামগুলি ব্যবহার করার চেয়ে EnumSetএস আরও বর্ধনযোগ্য হতে পারে, উদাহরণস্বরূপ EnumSet<Move> attacks = EnumSet.of(Move.ATTACK_HIGH, Move.ATTACK_LOW, ...);এবং তার attacks.contains(move)চেয়ে বরং এস এর move.type == MoveType.ATTACKব্যবহার EnumSetসম্ভবত সরাসরি সমান পরীক্ষার তুলনায় কিছুটা ধীর হতে হবে।


কেস যেখানে একটি সফল ব্লক একটি পাল্টা ফলাফল স্বরূপ, আপনি প্রতিস্থাপন করতে পারেন if (one.height == two.height) return LandedHit.NEITHER;সঙ্গে

if (one.height == two.height) {
    // Successful block results in a counter against the attacker
    if (one.isAttack()) return LandedHit.PLAYER_TWO;
    return LandedHit.PLAYER_ONE;
}

এছাড়াও, ifটেরিনারি অপারেটর ( boolean_expression ? result_if_true : result_if_false) এর ব্যবহারের সাথে কিছু বিবৃতি প্রতিস্থাপনের ফলে কোডটি আরও কমপ্যাক্ট হয়ে উঠতে পারে (উদাহরণস্বরূপ, পূর্ববর্তী ব্লকের কোডটি হয়ে উঠত return one.isAttack() ? LandedHit.PLAYER_TWO : LandedHit.PLAYER_ONE;), তবে এটি কঠোরভাবে পঠনযোগ্য oneliners হতে পারে তাই আমি চাইতাম না ' টি আরও জটিল শাখার জন্য এটি প্রস্তাব।


আমি অবশ্যই এটি সন্ধান করব তবে আমার বর্তমান কোডটি আমাকে আমার স্প্রিটশিটে শুরুর পয়েন্ট হিসাবে ব্যবহার করতে oneএবং twoপুনরায় ব্যবহার করার অনুমতি দেয় । যদিও এটির জন্য অনুমতি দেওয়ার জন্য এটি অতিরিক্ত অতিরিক্ত কোডের প্রয়োজন হয় না।
টমফर्थ

2
@ টোমফર્થ৪৮ এখানে এমন একটি EnumMapশ্রেণি রয়েছে যা আপনি আপনার পূর্ণসংখ্যার অফসেটগুলিতে এনামগুলিকে মানচিত্র করতে ব্যবহার করতে পারেন (আপনি এনাম সদস্যদের সাধারণ মানগুলি সরাসরি ব্যবহার করতে পারেন, যেমন Move.ATTACK_HIGH.ordinal()হবে 0, Move.ATTACK_LOW.ordinal()হবে 1ইত্যাদি), তবে এটি স্পষ্টভাবে তুলনায় আরও ভঙ্গুর / কম নমনীয় বিদ্যমান সদস্যদের মধ্যে এনাম মান যোগ করার জন্য প্রতিটি সদস্যকে একটি মানের সাথে যুক্ত করা গণনাটি বাতিল করে দেবে, যা কোনও ক্ষেত্রেই হবে না EnumMap))
জ্যাব

7
এটি সর্বাধিক পঠনযোগ্য সমাধান কারণ কোডটি এমন কিছুতে অনুবাদ করে যা কোডটি পড়া ব্যক্তিটির পক্ষে অর্থবহ।
ডেভিড স্ট্যানলি

আপনার কোড, কমপক্ষে একটি এনাম ব্যবহার করা ভুল, ভুল। ওপিতে একটি সফলফুল ব্লকের বিবৃতি অনুসারে আক্রমণকারীর উপর আঘাত হানা যায়। অর্থবহুল কোডের জন্য তবে +1।
তাইমির

2
এমনকি আপনি এনামের সাথে একটি attack(against)পদ্ধতি যুক্ত করতে পারেন Move, এই পদক্ষেপটি একটি সফল আক্রমণে ফিরে এসে এইচআইটি ফিরিয়ে দিতে পারেন, যখন পদক্ষেপটি একটি অবরুদ্ধ আক্রমণ হয়ে থাকে তখন ব্যাকফায়ার এবং যখন আক্রমণ হয় না তখন কিছুই হয় না। এই ভাবে আপনি সাধারণ (এটা বাস্তবায়ন করতে পারে public boolean attack(Move other) { if this.isAttack() return (other.isAttack() || other.height != this.height) ? HIT : BACKFIRE; return NOTHING; }), এবং প্রয়োজন হলে নির্দিষ্ট প্যাচসমূহ উপর ওভাররাইড (দুর্বল প্যাচসমূহ যা কোনো ব্লক ব্লক করে দিতে পারেন, আক্রমণ যা কখনো বিপর্যয় ঘটা ইত্যাদি)
পুনর্লিখিত

50

একটি অ্যারে ব্যবহার করবেন না কেন?

আমি শুরু থেকে শুরু করব। আমি একটি প্যাটার্ন দেখছি, মানগুলি 0 থেকে 3 পর্যন্ত চলে যায় এবং আপনি সমস্ত সম্ভাব্য মানগুলি ধরতে চান। এটি আপনার টেবিল:

0 & 0 = 0
0 & 1 = 0
0 & 2 = 1
0 & 3 = 2
1 & 0 = 0
1 & 1 = 0
1 & 2 = 2
1 & 3 = 1
2 & 0 = 2
2 & 1 = 1
2 & 2 = 3
2 & 3 = 3
3 & 0 = 2
3 & 1 = 1
3 & 2 = 3
3 & 3 = 3

আমরা যখন এই একই টেবিল বাইনারি তাকান আমরা নিম্নলিখিত ফলাফল দেখতে:

00 & 00 = 00
00 & 01 = 00
00 & 10 = 01
00 & 11 = 10
01 & 00 = 00
01 & 01 = 00
01 & 10 = 10
01 & 11 = 01
10 & 00 = 10
10 & 01 = 01
10 & 10 = 11
10 & 11 = 11
11 & 00 = 10
11 & 01 = 01
11 & 10 = 11
11 & 11 = 11

এখন আপনি ইতিমধ্যে কিছু প্যাটার্ন দেখতে পাচ্ছেন তবে আমি যখন এক এবং দুটি মান একত্রিত করি তখন আমি দেখতে পাচ্ছি আপনি 0000, 0001, 0010, ..... 1110 এবং 1111 সব মান ব্যবহার করছেন Now এখন আসুন এক এবং দুটি মান একত্রিত করার জন্য একটি একক করতে 4 বিট পূর্ণসংখ্যা।

0000 = 00
0001 = 00
0010 = 01
0011 = 10
0100 = 00
0101 = 00
0110 = 10
0111 = 01
1000 = 10
1001 = 01
1010 = 11
1011 = 11
1100 = 10
1101 = 01
1110 = 11
1111 = 11

আমরা যখন এটি দশমিক মানগুলিতে অনুবাদ করি আমরা একটি খুব সম্ভাব্য মানের অ্যারে দেখতে পাই যেখানে এক এবং দুটি সংযুক্তকে সূচক হিসাবে ব্যবহার করা যেতে পারে:

0 = 0
1 = 0
2 = 1
3 = 2
4 = 0
5 = 0
6 = 2
7 = 1
8 = 2
9 = 1
10 = 3
11 = 3
12 = 2
13 = 1
14 = 3
15 = 3

অ্যারে তখন {0, 0, 1, 2, 0, 0, 2, 1, 2, 1, 3, 3, 2, 1, 3, 3}, যেখানে এটি সূচকটি কেবল এক এবং দুটি সংযুক্ত।

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

int[] myIntArray = {0, 0, 1, 2, 0, 0, 2, 1, 2, 1, 3, 3, 2, 1, 3, 3};
result = myIntArray[one * 4 + two]; 

আমি জানি না 2 দ্বারা বিটশিফ্টটি গুণণের চেয়ে দ্রুত কিনা। তবে এটি চেষ্টা করার মতো হতে পারে।


2
2 এর বিট-শিফট 4 এর গুণকের চেয়ে প্রায় স্পষ্টভাবে দ্রুত best সত্যি বলতে, আমার কাছে শিফটটি আরও বেশি পঠনযোগ্য।
ক্রুঙ্কার

আমি আপনার পদ্ধতির পছন্দ! এটি মূলত একটি 4x4 ম্যাট্রিক্সকে 16 টি উপাদান অ্যারেতে সমতল করে।
ক্যামেরন টিঙ্কার

6
আজকাল, যদি আমার ভুল না হয় তবে সংকলকটি নিঃসন্দেহে স্বীকৃতি দেবে যে আপনি দু'জনের দ্বারা গুণাচ্ছেন এবং সেই অনুযায়ী এটি অপ্টিমাইজ করবেন। সুতরাং আপনার জন্য, প্রোগ্রামার, বিট শিফট এবং গুণটির একই কর্মক্ষমতা থাকা উচিত।
ট্যানার সোয়েট

24

এটি কিছুটা বিটম্যাজিক ব্যবহার করে (আপনি ইতিমধ্যে একক পূর্ণসংখ্যায় দুটি বিট তথ্য (কম / উচ্চ এবং আক্রমণ / ব্লক) ধরে এটি করছেন):

আমি এটি চালাইনি, কেবল এটি এখানে টাইপ করেছি, দয়া করে ডাবল চেক করুন। ধারণা অবশ্যই কাজ করে। সম্পাদনা: এটি এখন প্রতিটি ইনপুট জন্য পরীক্ষা করা হয়, কাজ করে।

public int fightMath(int one, int two) {
    if(one<2 && two<2){ //both players blocking
        return 0; // nobody hits
    }else if(one>1 && two>1){ //both players attacking
        return 3; // both hit
    }else{ // some of them attack, other one blocks
        int different_height = (one ^ two) & 1; // is 0 if they are both going for the same height - i.e. blocker wins, and 1 if height is different, thus attacker wins
        int attacker = one>1?1:0; // is 1 if one is the attacker, two is the blocker, and 0 if one is the blocker, two is the attacker
        return (attacker ^ different_height) + 1;
    }
}

অথবা আমি কি তথ্য দুটি বিট পৃথক ভেরিয়েবল মধ্যে পৃথক করার পরামর্শ দিতে হবে? উপরের মত বিট অপারেশনের উপর ভিত্তি করে কোডটি সাধারণত বজায় রাখা সত্যিই শক্ত।


2
আমি এই সমাধানের সাথে একমত, মূল প্রশ্নটিতে আমার মন্তব্যে আমার মনে যা ছিল তা অনেকটা দেখতে দেখতে অনেকটা দেখতে দেখতে। আমি এটিকে পৃথক ভেরিয়েবলগুলিতে বিভক্ত করতে পছন্দ করব, এটি ভবিষ্যতে উদাহরণস্বরূপ মধ্যম আক্রমণ যুক্ত করা সহজ করে তুলবে।
ইয়াহ

2
আমি পরীক্ষার পরে উপরের কোডে কিছু বাগগুলি ঠিক করেছি, এখন এটি ভালভাবে কাজ করে। বিট-ম্যানিপুলেটারের পথে আরও এগিয়ে গিয়ে আমি একটি লাইন সমাধানও নিয়ে এসেছি, যা এখনও অন্য উত্তরে বিটমাস্কের মতো রহস্যময় নয়, তবে এখনও আপনার মনকে return ((one ^ two) & 2) == 0 ? (one & 2) / 2 * 3 : ((one & 2) / 2 ^ ((one ^ two) & 1)) + 1;
আঁকানোর

1
এটি যে কোনও নতুন প্রোগ্রামার পড়ার কারণে এটি সর্বোত্তম উত্তর যা আসলে those সমস্ত ম্যাজিক সংখ্যার পিছনে কী ঘটছে তা বুঝতে পারবে।
বেজম্যাক্স

20

বেশ সত্য কথা বলতে গেলে প্রত্যেকেরই কোডের নিজস্ব স্টাইল থাকে। আমি ভাবিনি কর্মক্ষমতা খুব বেশি প্রভাবিত হবে। আপনি যদি স্যুইচ কেস সংস্করণ ব্যবহার করার চেয়ে এটি আরও ভাল করে বুঝতে পারেন তবে এটি ব্যবহার করে চালিয়ে যান।

আপনি যদি আইএফএস বাসা বেঁধে নিতে পারেন, তাই সম্ভবত আপনার শেষের জন্য কিছুটা পারফরম্যান্স বাড়তে পারে যদি চেকগুলি বিবৃতি হিসাবে অনেকের মধ্যে না যায়। তবে আপনার বেসিক জাভা কোর্সের প্রসঙ্গে এটি সম্ভবত উপকৃত হবে না।

else if(one == 3 && two == 3) { result = 3; }

সুতরাং, পরিবর্তে ...

if(one == 0 && two == 0) { result = 0; }
else if(one == 0 && two == 1) { result = 0; }
else if(one == 0 && two == 2) { result = 1; }
else if(one == 0 && two == 3) { result = 2; }

তুমি কর ...

if(one == 0) 
{ 
    if(two == 0) { result = 0; }
    else if(two == 1) { result = 0; }
    else if(two == 2) { result = 1; }
    else if(two == 3) { result = 2; }
}

আপনি পছন্দ হিসাবে এটি পুনরায় ফর্ম্যাট।

এটি কোডটি আরও ভাল দেখায় না, তবে আমি বিশ্বাস করি এটির সামান্য গতি বাড়ায়।


3
এটি সত্যিই ভাল অনুশীলন কিনা তা জানেন না তবে এই ক্ষেত্রে আমি সম্ভবত নেস্টেড সুইচ স্টেটমেন্ট ব্যবহার করব। এটি আরও জায়গা লাগবে তবে এটি সত্যই স্পষ্ট হবে।
রঞ্জকদৃষ্টি

এটিও কাজ করবে তবে আমার ধারণা এটি পছন্দ করার বিষয়। আমি আসলে পছন্দ করি যদি বিবৃতিগুলি কার্যত কোডটি কী করছে তা বলছে। আপনার মতামত অবশ্যই রাখবেন না, যা আপনার পক্ষে কার্যকর হয় :)। বিকল্প পরামর্শের জন্য আপভোট যদিও!
জো হার্পার

12

আসুন আমরা কি জানি দেখুন

1: আপনার উত্তরগুলি পি 1 (প্লেয়ার ওয়ান) এবং পি 2 (প্লেয়ার দু'জনের) জন্য প্রতিসম। এটি একটি যুদ্ধের খেলাগুলির জন্য অর্থবোধ করে তবে এটি আপনার যুক্তিটি উন্নত করতে আপনি সুবিধা নিতে পারেন।

2: 3 বীট 0 বেট 2 বিট 1 বিট 3 কেবলমাত্র এই কেসগুলি আচ্ছাদিত নয় এমনটি 0 বনাম 1 এবং 2 বনাম 3 এর সংমিশ্রণ it এটি অন্যভাবে রাখার জন্য অনন্য বিজয় টেবিলটি দেখতে এরকম: 0 বিট 2, 1 বিট 3, 2 বীট 1, 3 বেট 0

3: যদি 0/1 একে অপরের বিরুদ্ধে যায় তবে একটি হিটলেস ড্র আছে তবে যদি 2/3 একে অপরের বিরুদ্ধে যায় তবে উভয়ই হিট

প্রথমে আসুন, আমরা যদি একটি জয়লাভ করি তবে আমাদের জানাতে একমুখী ফাংশন তৈরি করি:

// returns whether we beat our opponent
public boolean doesBeat(int attacker, int defender) {
  int[] beats = {2, 3, 1, 0};
  return defender == beats[attacker];
}

তারপরে আমরা চূড়ান্ত ফলাফল রচনা করতে এই ফাংশনটি ব্যবহার করতে পারি:

// returns the overall fight result
// bit 0 = one hits
// bit 1 = two hits
public int fightMath(int one, int two)
{
  // Check to see whether either has an outright winning combo
  if (doesBeat(one, two))
    return 1;

  if (doesBeat(two, one))
    return 2;

  // If both have 0/1 then its hitless draw but if both have 2/3 then they both hit.
  // We can check this by seeing whether the second bit is set and we need only check
  // one's value as combinations where they don't both have 0/1 or 2/3 have already
  // been dealt with 
  return (one & 2) ? 3 : 0;
}

যদিও এটি যুক্তিযুক্তভাবে আরও জটিল এবং অনেক উত্তরে প্রস্তাবিত টেবিলের চেয়ে কম ধীরে ধীরে আমি বিশ্বাস করি এটি একটি সর্বোত্তম পদ্ধতি কারণ এটি আসলে আপনার কোডের যুক্তি সংযুক্ত করে এবং আপনার কোডটি যে পড়ছে তার কাছে এটি বর্ণনা করে। আমি মনে করি এটি এটিকে আরও ভাল বাস্তবায়ন করে তোলে।

(সিনট্যাক্স বন্ধ থাকলে আমি কোনও জাভা তাই ক্ষমা চেয়েছি এমন কিছুক্ষণ হয়ে গেছে, আশা করি যদি এটি কিছুটা ভুল হয়ে যায় তবে এটি এখনও বোধগম্য)

যাইহোক, 0-3 স্পষ্টভাবে কিছু বোঝায় ; এগুলি স্বেচ্ছাচারিত মান নয় তাই এটি তাদের নামকরণে সহায়তা করবে।


11

আমি আশা করি আমি যুক্তিটি সঠিকভাবে বুঝতে পেরেছি। যেমন কিছু সম্পর্কে:

public int fightMath (int one, int two)
{
    int oneHit = ((one == 3 && two != 1) || (one == 2 && two != 0)) ? 1 : 0;
    int twoHit = ((two == 3 && one != 1) || (two == 2 && one != 0)) ? 2 : 0;

    return oneHit+twoHit;
}

একটি হিট উচ্চ বা একটি হিট লো চেক করা অবরুদ্ধ নয় এবং প্লেয়ার দু'জনের জন্য একই।

সম্পাদনা: অ্যালগরিদম পুরোপুরি বোঝা যায় নি, "হিট" ব্লক করার সময় পুরষ্কার দেওয়া হয়েছিল যা আমি বুঝতে পারি নি (থেক্স ইলিয়াস):

public int fightMath (int one, int two)
{
    int oneAttack = ((one == 3 && two != 1) || (one == 2 && two != 0)) ? 1 : (one >= 2) ? 2 : 0;
    int twoAttack = ((two == 3 && one != 1) || (two == 2 && one != 0)) ? 2 : (two >= 2) ? 1 : 0;

    return oneAttack | twoAttack;
}

প্যাটারকে দুর্দান্ত ফলাফলের উপায়!
চাদ

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

বুঝতে পারিনি যে "হিট" ব্লকের জন্য ভূষিত করা হয়েছিল। এটা ইশারা জন্য ধন্যবাদ। খুব সাধারণ ফিক্স সঙ্গে সামঞ্জস্য।
ক্রিস

10

জাভা নিয়ে আমার অভিজ্ঞতা নেই তাই কিছু টাইপস থাকতে পারে। দয়া করে কোডটি সিউডো-কোড হিসাবে বিবেচনা করুন।

আমি একটি সরল সুইচ সঙ্গে যেতে হবে। তার জন্য, আপনার একক সংখ্যা মূল্যায়ন প্রয়োজন need তবে, এই ক্ষেত্রে, যেহেতু 0 <= one < 4 <= 9এবং 0 <= two < 4 <= 9, আমরা one10 দ্বারা গুণিত করে এবং যোগ করে উভয় ইনটকে একটি সাধারণ ইনটকে রূপান্তর করতে পারি two। তারপরে ফলাফলের মতো সংখ্যায় একটি স্যুইচ ব্যবহার করুন:

public int fightMath(int one, int two) {
    // Convert one and two to a single variable in base 10
    int evaluate = one * 10 + two;

    switch(evaluate) {
        // I'd consider a comment in each line here and in the original code
        // for clarity
        case 0: result = 0; break;
        case 1: result = 0; break;
        case 1: result = 0; break;
        case 2: result = 1; break;
        case 3: result = 2; break;
        case 10: result = 0; break;
        case 11: result = 0; break;
        case 12: result = 2; break;
        case 13: result = 1; break;
        case 20: result = 2; break;
        case 21: result = 1; break;
        case 22: result = 3; break;
        case 23: result = 3; break;
        case 30: result = 1; break;
        case 31: result = 2; break;
        case 32: result = 3; break;
        case 33: result = 3; break;
    }

    return result;
}

এখানে আরও একটি ছোট পদ্ধতি আছে যা আমি কেবল একটি তাত্ত্বিক কোড হিসাবে চিহ্নিত করতে চাই। তবে আমি এটি ব্যবহার করব না কারণ এতে কিছু অতিরিক্ত জটিলতা রয়েছে যা আপনি সাধারণত মোকাবেলা করতে চান না। অতিরিক্ত জটিলতা বেস 4 থেকে আসে কারণ গণনা 0, 1, 2, 3, 10, 11, 12, 13, 20, ...

public int fightMath(int one, int two) {
    // Convert one and two to a single variable in base 4
    int evaluate = one * 4 + two;

    allresults = new int[] { 0, 0, 1, 2, 0, 0, 2, 1, 2, 1, 3, 3, 1, 2, 3, 3 };

    return allresults[evaluate];
}

সত্যিই কেবল অতিরিক্ত নোট, যদি আমি জাভা থেকে কিছু হারিয়েছি। পিএইচপি-তে আমি করতাম:

function fightMath($one, $two) {
    // Convert one and two to a single variable in base 4
    $evaluate = $one * 10 + $two;

    $allresults = array(
         0 => 0,  1 => 0,  2 => 1,  3 => 2,
        10 => 0, 11 => 0, 12 => 2, 13 => 1,
        20 => 2, 21 => 1, 22 => 3, 23 => 3,
        30 => 1, 31 => 2, 32 => 3, 33 => 3 );

    return $allresults[$evaluate];
}

অষ্টম সংস্করণের আগে জাভাতে কোনও লামদাস নেই
কিরিল গাজাজকভ

1
এই. এত সংখ্যক ইনপুটগুলির জন্য, আমি একটি সংমিশ্রিত মান সহ একটি স্যুইচ ব্যবহার করতাম (যদিও এটি 10 ​​বা এর বেশি গুণক যেমন 100 বা 1000 এর সাথে আরও পঠনযোগ্য হতে পারে)।
মেডিনোক

7

যেহেতু আপনি নেস্টেড ifশর্তাদি পছন্দ করেন , তাই এখানে অন্য উপায়।
দ্রষ্টব্য যে এটি resultসদস্যকে ব্যবহার করে না এবং এটি কোনও রাজ্য পরিবর্তন করে না।

public int fightMath(int one, int two) {
    if (one == 0) {
      if (two == 0) { return 0; }
      if (two == 1) { return 0; }
      if (two == 2) { return 1; }
      if (two == 3) { return 2; }
    }   
    if (one == 1) {
      if (two == 0) { return 0; }
      if (two == 1) { return 0; }
      if (two == 2) { return 2; }
      if (two == 3) { return 1; }
    }
    if (one == 2) {
      if (two == 0) { return 2; }
      if (two == 1) { return 1; }
      if (two == 2) { return 3; }
      if (two == 3) { return 3; }
    }
    if (one == 3) {
      if (two == 0) { return 1; }
      if (two == 1) { return 2; }
      if (two == 2) { return 3; }
      if (two == 3) { return 3; }
    }
    return DEFAULT_RESULT;
}

তোমার আর কারও নেই কেন?
এফডিনফ

3
@ এফডিনফ আমি elseচেইন ব্যবহার করতে পারতাম তবে এতে কোনও পার্থক্য হত না।
নিক ডানডৌলাকিস

1
আমি জানি এটি তুচ্ছ, তবে অন্য চেইনগুলি দ্রুত কার্যকর করা যাবে না? 4 টির মধ্যে 3 ক্ষেত্রে? আমি সবসময় কোড লেখার অভ্যাস করি যত তাড়াতাড়ি সম্ভব কার্যকর করতে যত তাড়াতাড়ি কয়েকটা চক্রই কার্যকর করা যায়।
ব্র্যান্ডন বেডেন

2
@ ব্র্যান্ডনবেদারন এখানে তারা কোন পার্থক্য করবে না (ধরে নিবেন ইনপুটটি সর্বদা 0..3 এর মধ্যে থাকে)। সংকলক সম্ভবত যাইহোক কোড মাইক্রো অপ্টিমাইজ করবে। যদি আমাদের দীর্ঘ else ifবিবৃতিতে বিবৃতি থাকে তবে আমরা কোডগুলি গতি switchবা টেবিলে সন্ধান করতে পারি।
নিক ডানডৌলাকিস

এটা কিভাবে? যদি one==0এটি কোডটি চালায়, তবে এটি পরীক্ষা করতে হবে যদি one==1তা ছিল কিনা one==2এবং শেষ পর্যন্ত যদি one==3- যদি সেখানে অন্য কিছু থাকে তবে এটি শেষ তিনটি চেক না করায় কারণ এটি প্রথম ম্যাচের পরে বিবৃতিটি প্রস্থান করবে। এবং হ্যাঁ, আপনি বিবৃতিগুলির স্থানে একটি স্যুইচ স্টেটমেন্ট if (one...ব্যবহার করে এবং তারপরে আরও কেসের ক্ষেত্রে আরও একটি সুইচ ব্যবহার করে আরও অনুকূলিত করতে পারেন one's। তবে এটি আমার প্রশ্ন নয়।
ব্র্যান্ডন বেডেন

6

সুইচ কেসিং দিয়ে এটি ব্যবহার করে দেখুন ..

দেখে নিন এখানে বা এখানে এটি সম্পর্কে আরও তথ্যের জন্য

switch (expression)
{ 
  case constant:
        statements;
        break;
  [ case constant-2:
        statements;
        break;  ] ...
  [ default:
        statements;
        break;  ] ...
}

আপনি এটিতে একাধিক শর্ত (একসাথে নয়) যুক্ত করতে পারেন এমনকি একটি ডিফল্ট বিকল্পও থাকতে পারে যেখানে অন্য কোনও মামলা সন্তুষ্ট হয়নি।

PS: শুধুমাত্র একটি শর্ত সন্তুষ্ট করতে হলে ..

যদি 2 কন্ডিশন একসাথে উত্থাপিত হয় .. আমি মনে করি না যে স্যুইচ ব্যবহার করা যেতে পারে। তবে আপনি এখানে আপনার কোড হ্রাস করতে পারেন।

জাভা সুইচ বিবৃতি একাধিক ক্ষেত্রে


6

আমার কাছে প্রথম যে বিষয়টি ঘটেছে তা হ'ল ফ্রান্সিসকো প্রেজেনসিয়ার দেওয়া একই উত্তরটি, তবে কিছুটা অনুকূল ছিল:

public int fightMath(int one, int two)
{
    switch (one*10 + two)
    {
    case  0:
    case  1:
    case 10:
    case 11:
        return 0;
    case  2:
    case 13:
    case 21:
    case 30:
        return 1;
    case  3:
    case 12:
    case 20:
    case 31:
        return 2;
    case 22:
    case 23:
    case 32:
    case 33:
        return 3;
    }
}

আপনি সর্বশেষ কেসটিকে (3 এর জন্য) ডিফল্ট কেস করে এটি আরও অনুকূল করতে পারেন:

    //case 22:
    //case 23:
    //case 32:
    //case 33:
    default:
        return 3;

এই পদ্ধতির সুবিধাটি হ'ল অন্যান্য প্রস্তাবিত পদ্ধতির তুলনায় কোনও মানগুলি কীসের জন্য প্রতীয়মান oneএবং তার twoসাথে সঙ্গতিপূর্ণ তা দেখা সহজ ।


এই খনি অন্য উত্তর একটি প্রকরণ হয় এখানে
ডেভিড আর ট্রাইবল

6
((two&2)*(1+((one^two)&1))+(one&2)*(2-((one^two)&1)))/2

4
আপনার এটি আসতে কতক্ষণ সময় লাগল?
mbatchkarov

2
@ এমবাচকারভ অন্যান্য উত্তরগুলি পড়ার প্রায় 10 মিনিট, তারপরে পেনসিল এবং কাগজ দিয়ে 10 মিনিটের স্ক্রাবলিং করে।
দাউদ ইবনে কেরেম

7
আমি যদি এটি বজায় রাখতে পারি তবে আমি সত্যিই দুঃখ বোধ করব।
মেরিওভি

উম্মম্ম ... একটি ত্রুটি রয়েছে: আপনি নিখোঁজ রয়েছেন; --unicorns
আলবার্তো

আমি @ মেরিওভির সাথে একমত, সংক্ষিপ্ত হওয়ার প্রপস, এখনও এপিএল কোডের মতো ভয়াবহ
এড গ্রিবেল

4

আপনি একাধিকের পরিবর্তে একটি স্যুইচ কেস ব্যবহার করতে পারেনif

এছাড়াও উল্লেখ করতে হবে যেহেতু আপনার দুটি ভেরিয়েবল রয়েছে তাই আপনার দুটি পরিবর্তনশীলগুলি স্যুইচটিতে ব্যবহার করতে আপনাকে মার্জ করতে হবে

দুটি ভেরিয়েবল পরিচালনা করতে এই জাভা স্যুইচ স্টেটমেন্টটি পরীক্ষা করে দেখুন ?


3

আমি এক / দুই এবং ফলাফলের মধ্যে একটি টেবিল আঁকতে আমি একটি প্যাটার্ন দেখতে পাচ্ছি,

if(one<2 && two <2) result=0; return;

যদি বিবৃতি দেওয়া হয় তবে উপরেরটি কমপক্ষে 3 কেটে ফেলবে। আমি কোনও সেট প্যাটার্ন দেখতে পাচ্ছি না বা প্রদত্ত কোড থেকে আমি খুব বেশি পরিমাণে সংগ্রহ করতে সক্ষম নই - তবে যদি এই জাতীয় যুক্তিটি উত্পন্ন করা যায় তবে এটি বিবৃতিতে অনেকগুলি কেটে ফেলবে।

আশাকরি এটা সাহায্য করবে.


3

একটি ভাল বিষয় হ'ল নিয়মকে পাঠ্য হিসাবে সংজ্ঞায়িত করা, আপনি তখন সঠিক সূত্রটি আরও সহজেই অর্জন করতে পারেন। এটি লাল্টোর দুর্দান্ত অ্যারে উপস্থাপনা থেকে নেওয়া হয়েছে:

{ 0, 0, 1, 2 },
{ 0, 0, 2, 1 },
{ 2, 1, 3, 3 },
{ 1, 2, 3, 3 }

এবং এখানে আমরা কিছু সাধারণ মন্তব্য সহ যাই, তবে আপনার বিধি অনুসারে তাদের বর্ণনা করা উচিত:

if(one<2) // left half
{
    if(two<2) // upper left half
    {
        result = 0; //neither hits
    }
    else // lower left half
    {
        result = 1+(one+two)%2; //p2 hits if sum is even
    }
}
else // right half
{
    if(two<2) // upper right half
    {
        result = 1+(one+two+1)%2; //p1 hits if sum is even
    }
    else // lower right half
    {
        return 3; //both hit
    }
}

আপনি অবশ্যই এটিকে কম কোডে নামিয়ে আনতে পারেন তবে কমপ্যাক্ট সমাধানের চেয়ে আপনি কী কোড কোড করেন তা বোঝা ভাল।

if((one<2)&&(two<2)) result = 0; //top left
else if((one>1)&&(two>1)) result = 3; //bottom right
else result = 1+(one+two+((one>1)?1:0))%2; //no idea what that means

জটিল পি 1 / পি 2 হিট সম্পর্কে কিছু ব্যাখ্যা দুর্দান্ত লাগবে, আকর্ষণীয় দেখায়!


3

সংক্ষিপ্ত এবং এখনও পঠনযোগ্য সমাধান:

static public int fightMath(int one, int two)
{
    if (one < 2 && two < 2) return 0;
    if (one > 1 && two > 1) return 3;
    int n = (one + two) % 2;
    return one < two ? 1 + n : 2 - n;
}

বা আরও ছোট:

static public int fightMath(int one, int two)
{
    if (one / 2 == two / 2) return (one / 2) * 3;
    return 1 + (one + two + one / 2) % 2;
}

কোনও "ম্যাজিক" নম্বর থাকে না;) আশা করি এটি সাহায্য করবে।


2
এই জাতীয় সূত্রগুলি পরবর্তী তারিখে সংমিশ্রণের ফলাফল পরিবর্তন করা (আপডেট) করা অসম্ভব করে দেবে। একমাত্র উপায় হ'ল পুরো সূত্রটি পুনরায় কাজ করা।
এসএনএজি

2
@ এসএনএজি: আমি এর সাথে একমত সর্বাধিক নমনীয় সমাধান হ'ল 2 ডি অ্যারে ব্যবহার করা। তবে এই পোস্টের অটোর একটি সূত্র চেয়েছিল এবং এটি কেবলমাত্র সাধারণ আইএফএস এবং গণিতের সাহায্যে পাওয়া সেরা।
পিডব্লিউ

2

static int val(int i, int u){ int q = (i & 1) ^ (u & 1); return ((i >> 1) << (1 ^ q))|((u >> 1) << q); }


1

আমি ব্যক্তিগতভাবে টেরিনারি অপারেটরদের ক্যাসকেড করতে পছন্দ করি:

int result = condition1
    ? result1
    : condition2
    ? result2
    : condition3
    ? result3
    : resultElse;

তবে আপনার ক্ষেত্রে, আপনি ব্যবহার করতে পারেন:

final int[] result = new int[/*16*/] {
    0, 0, 1, 2,
    0, 0, 2, 1,
    2, 1, 3, 3,
    1, 2, 3, 3
};

public int fightMath(int one, int two) {
    return result[one*4 + two];
}

বা, আপনি বিটগুলিতে একটি প্যাটার্ন লক্ষ্য করতে পারেন:

one   two   result

section 1: higher bits are equals =>
both result bits are equals to that higher bits

00    00    00
00    01    00
01    00    00
01    01    00
10    10    11
10    11    11
11    10    11
11    11    11

section 2: higher bits are different =>
lower result bit is inverse of lower bit of 'two'
higher result bit is lower bit of 'two'

00    10    01
00    11    10
01    10    10
01    11    01
10    00    10
10    01    01
11    00    01
11    01    10

সুতরাং আপনি যাদু ব্যবহার করতে পারেন:

int fightMath(int one, int two) {
    int b1 = one & 2, b2 = two & 2;
    if (b1 == b2)
        return b1 | (b1 >> 1);

    b1 = two & 1;

    return (b1 << 1) | (~b1);
}

1

এখানে মোটামুটি সংক্ষিপ্ত সংস্করণ রয়েছে, যা জবাবের প্রতিক্রিয়ার অনুরূপ । এটি সঞ্চয় করতে একটি মানচিত্র ব্যবহার করে যা অন্যের উপর বিজয় সঞ্চার করে।

public enum Result {
  P1Win, P2Win, BothWin, NeitherWin;
}

public enum Move {
  BLOCK_HIGH, BLOCK_LOW, ATTACK_HIGH, ATTACK_LOW;

  static final Map<Move, List<Move>> beats = new EnumMap<Move, List<Move>>(
      Move.class);

  static {
    beats.put(BLOCK_HIGH, new ArrayList<Move>());
    beats.put(BLOCK_LOW, new ArrayList<Move>());
    beats.put(ATTACK_HIGH, Arrays.asList(ATTACK_LOW, BLOCK_LOW));
    beats.put(ATTACK_LOW, Arrays.asList(ATTACK_HIGH, BLOCK_HIGH));
  }

  public static Result compare(Move p1Move, Move p2Move) {
    boolean p1Wins = beats.get(p1Move).contains(p2Move);
    boolean p2Wins = beats.get(p2Move).contains(p1Move);

    if (p1Wins) {
      return (p2Wins) ? Result.BothWin : Result.P1Win;
    }
    if (p2Wins) {
      return (p1Wins) ? Result.BothWin : Result.P2Win;
    }

    return Result.NeitherWin;
  }
} 

উদাহরণ:

System.out.println(Move.compare(Move.ATTACK_HIGH, Move.BLOCK_LOW));

ছাপে:

P1Win

static final Map<Move, List<Move>> beats = new java.util.EnumMap<>();পরিবর্তে আমি সুপারিশ করব , এটি কিছুটা দক্ষ হবে।
জ্যাব

@ জ্যাব হ্যাঁ, ভাল ধারণা। আমি সর্বদা ভুলে যাই যে টাইপটি বিদ্যমান। এবং ... এটি নির্মাণ করা কত বিশ্রী!
ডানকান জোন্স

1

আমি একটি মানচিত্র, একটি হ্যাশম্যাপ বা একটি ট্রিম্যাপ ব্যবহার করব

বিশেষত যদি পরামিতিগুলি ফর্মটিতে না থাকে 0 <= X < N

এলোমেলো ধনাত্মক পূর্ণসংখ্যার সেটের মতো ..

কোড

public class MyMap
{
    private TreeMap<String,Integer> map;

    public MyMap ()
    {
        map = new TreeMap<String,Integer> ();
    }

    public void put (int key1, int key2, Integer value)
    {
        String key = (key1+":"+key2);

        map.put(key, new Integer(value));
    }

    public Integer get (int key1, int key2)
    {
        String key = (key1+":"+key2);

        return map.get(key);
    }
}

1

@ জো হার্পারকে ধন্যবাদ জানাই যে আমি তার উত্তরের বিভিন্নতা ব্যবহার করে শেষ করেছি। এটিকে আরও সরু করার জন্য প্রতি 4 টি হিসাবে 2 টি ফলাফল একই রকম ছিল আমি আরও নীচে নামিয়েছিলাম।

আমি এই সময়ে ফিরে আসতে পারি, তবে যদি একাধিক- ifস্তরের কারণে কোনও বড় প্রতিরোধের ব্যবস্থা না আসে তবে আমি এখনই এটি রাখব। আমি টেবিল ম্যাট্রিক্স এবং আরও বিবৃতি সমাধান স্যুইচ করব।

public int fightMath(int one, int two) {
  if (one === 0) {
    if (two === 2) { return 1; }
    else if(two === 3) { return 2; }
    else { return 0; }
  } else if (one === 1) {
    if (two === 2) { return 2; }
    else if (two === 3) { return 1; }
    else { return 0; }
  } else if (one === 2) {
    if (two === 0) { return 2; }
    else if (two === 1) { return 1; }
    else { return 3; }
  } else if (one === 3) {
    if (two === 0) { return 1; }
    else if (two === 1) { return 2; }
    else { return 3; }
  }
}

13
এটি আসলে আসলটির চেয়ে কম পঠনযোগ্য এবং বিবৃতিগুলির সংখ্যা হ্রাস করে না ...
চাদ

@ চ্যাড এর ধারণাটি ছিল প্রক্রিয়াটির গতি বৃদ্ধি করা এবং এটি ভয়ঙ্কর বলে মনে হলেও ভবিষ্যতে আরও পদক্ষেপ যুক্ত করা উচিত এটি সহজেই আপডেট হয়। এটি বলে আমি এখন পূর্ববর্তী উত্তরটি ব্যবহার করছি যা আমি আগে পুরোপুরি বুঝতে পারি নি।
টমফर्थ

3
@ টোমফર્થ 84 কি এমন কোনও কারণ আছে যে আপনি যদি আপনার বিবৃতিগুলির জন্য যথাযথ কোডিং কনভেনশন অনুসরণ করেন না?
ylun.ca

@াইলুন: আমি লাইনে এটি আটকে দেওয়ার আগে কমিয়ে দিয়েছি, পাঠযোগ্যতার জন্য নয় বরং স্পষ্ট স্পেসের জন্য। এই পৃষ্ঠায় অনুশীলনের বিভিন্নতা রয়েছে এবং দুঃখের বিষয় এটি ঠিক আমি শিখেছি এবং এতে আরামদায়ক।
টমফर्थ

2
@ টমফিয়ার্থ ৮৪ আমি মনে করি না যে এটি সহজেই আপডেট হয়েছে, রেখার সংখ্যাটি অনুমোদিত মানগুলির সংখ্যার পণ্যের মতো কিছু বাড়ায়।
অ্যান্ড্রু লাজার

0
  1. কোডটি আরও পঠনযোগ্য করার জন্য ধ্রুবক বা এনাম ব্যবহার করুন
  2. কোডটি আরও ফাংশনে বিভক্ত করার চেষ্টা করুন
  3. সমস্যার প্রতিসাম্য ব্যবহার করার চেষ্টা করুন

এটি কীভাবে দেখতে পারা যায় তা এখানে একটি পরামর্শ, তবে এখানে একটি ints ব্যবহার করা এখনও একধরণের কুৎসিত:

static final int BLOCK_HIGH = 0;
static final int BLOCK_LOW = 1;
static final int ATTACK_HIGH = 2;
static final int ATTACK_LOW = 3;

public static int fightMath(int one, int two) {
    boolean player1Wins = handleAttack(one, two);
    boolean player2Wins = handleAttack(two, one);
    return encodeResult(player1Wins, player2Wins); 
}



private static boolean handleAttack(int one, int two) {
     return one == ATTACK_HIGH && two != BLOCK_HIGH
        || one == ATTACK_LOW && two != BLOCK_LOW
        || one == BLOCK_HIGH && two == ATTACK_HIGH
        || one == BLOCK_LOW && two == ATTACK_LOW;

}

private static int encodeResult(boolean player1Wins, boolean player2Wins) {
    return (player1Wins ? 1 : 0) + (player2Wins ? 2 : 0);
}

ইনপুট এবং আউটপুট জন্য একটি কাঠামোগত ধরনের ব্যবহার করা ভাল হবে। ইনপুটটির আসলে দুটি ক্ষেত্র রয়েছে: অবস্থান এবং ধরণ (ব্লক বা আক্রমণ)। আউটপুটটিতে দুটি ক্ষেত্র রয়েছে: প্লেয়ার 1 উইনস এবং প্লেয়ার 2 উইনস। এটি একটি একক পূর্ণসংখ্যার মধ্যে এনকোডিং কোড পড়া কঠিন করে তোলে।

class PlayerMove {
    PlayerMovePosition pos;
    PlayerMoveType type;
}

enum PlayerMovePosition {
    HIGH,LOW
}

enum PlayerMoveType {
    BLOCK,ATTACK
}

class AttackResult {
    boolean player1Wins;
    boolean player2Wins;

    public AttackResult(boolean player1Wins, boolean player2Wins) {
        this.player1Wins = player1Wins;
        this.player2Wins = player2Wins;
    }
}

AttackResult fightMath(PlayerMove a, PlayerMove b) {
    return new AttackResult(isWinningMove(a, b), isWinningMove(b, a));
}

boolean isWinningMove(PlayerMove a, PlayerMove b) {
    return a.type == PlayerMoveType.ATTACK && !successfulBlock(b, a)
            || successfulBlock(a, b);
}

boolean successfulBlock(PlayerMove a, PlayerMove b) {
    return a.type == PlayerMoveType.BLOCK 
            && b.type == PlayerMoveType.ATTACK 
            && a.pos == b.pos;
}

দুর্ভাগ্যক্রমে, জাভা এই ধরণের ডেটা-টাইপের প্রকাশে খুব ভাল নয়।


-2

পরিবর্তে এই জাতীয় কিছু

   public int fightMath(int one, int two) {
    return Calculate(one,two)

    }


    private int Calculate(int one,int two){

    if (one==0){
        if(two==0){
     //return value}
    }else if (one==1){
   // return value as per condtiion
    }

    }

4
আপনি সবেমাত্র একটি ব্যক্তিগত ফাংশন তৈরি করেছেন যা জনসাধারণের দ্বারা মোড়ানো। কেন শুধু জনসাধারণের অনুষ্ঠানে এটি বাস্তবায়ন করা হয় না?
মার্টিন উয়েডিং

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