গ মধ্যে গল্ফ করার জন্য টিপস


137

সি তে গল্ফ করার জন্য আপনার কাছে কোন সাধারণ টিপস রয়েছে? আমি এমন ধারণাগুলি সন্ধান করছি যা সাধারণভাবে কোড গল্ফ সমস্যার ক্ষেত্রে প্রয়োগ করা যেতে পারে যা কমপক্ষে কিছুটা সি এর সাথে নির্দিষ্ট (যেমন "মন্তব্যগুলি সরান" কোনও উত্তর নয়)। দয়া করে উত্তর প্রতি একটি টিপ পোস্ট করুন। এছাড়াও, দয়া করে অন্তর্ভুক্ত করুন যদি আপনার টিপটি C89 এবং / অথবা C99 এ প্রযোজ্য এবং যদি এটি কেবল নির্দিষ্ট সংকলকগুলিতে কাজ করে।


8
আমি মনে করি বৃহত্তম একক বাক্যটির ইঙ্গিতটি হ'ল: আইওসিসি-তে জমা দেওয়া বিজয়ী কোডগুলি পড়ুন।
vsz

উত্তর:


107

পূর্ণসংখ্যার মধ্যে অসমতার জন্য পরীক্ষা করতে বিটওয়াইস এক্সওআর ব্যবহার করুন:

if(a^b)পরিবর্তে if(a!=b)1 অক্ষর সংরক্ষণ করে।


73
a-bআপনাকে একই প্রভাব দেয়।
ugoren

22
একইভাবে আপনি এর a*bপরিবর্তে ব্যবহার করতে পারেন a&&b(ভিন্নতর প্রাধান্য রয়েছে, খারাপ হতে পারে বা নাও পারে)। আপনি যদি কোনও / =-বি জানেন (যেমন তারা স্বাক্ষরিত নয়) তবে a||b==a+b
16:30 এ ওয়ালেপ করুন

3
এটি আরও ভাল করে এটি এলোভিস অপারেটরের সাথে সংযুক্ত করুন ?:(যদি তার পরিবর্তে): উদাহরণস্বরূপ যদি কিছু আলাদা হয় তবে: a^b?_diff_:;
অলিভিয়ার ডুলাক

1
@ অলিভিয়ারডুলাক কি এমন একটি সংকলক আছে যা মিথ্যা শাখা থাকলে একটি খালি টের্নারি গ্রহণ করে?
জোনাথন ফ্রেচ 4'18

1
অ্যালভিয়ারডুলাক আপনি যাচাই করতে পারেন আমি যা জানি, জিসিসির একটি ?:অপারেটর রয়েছে যা কেবল সমানa ? a : b
ক্রোমিয়াম

75
  • mainএক বা একাধিক সংখ্যার ভেরিয়েবলগুলি ঘোষণার জন্য আপত্তিজনক যুক্তির তালিকা:

    main(a){for(;++a<28;)putchar(95+a);}
    

    ( প্রোগ্রামিং ভাষায় বর্ণমালার উত্তর )

    এই সমাধানটি a(ওরফে argc) হিসাবে শুরু হওয়ার বিষয়টিও অপব্যবহার করে 1তবে শর্ত থাকে যে প্রোগ্রামটিকে কোনও যুক্তি ছাড়াই ডাকা হবে।

  • জিনিসগুলিকে শূন্য করতে আরম্ভ করতে গ্লোবাল ভেরিয়েবল ব্যবহার করুন:

    t[52],i;main(c){for(;i<52;)(c=getchar())<11?i+=26:t[i+c-97]++;
    for(i=27;--i&&t[i-1]==t[i+25];);puts(i?"false":"true");}
    

    (উত্তর আনগ্রামগ্রাম গল্ফের ! )


62

কমা অপারেটর ব্রেসগুলি এড়িয়ে গিয়ে একক ব্লকে একাধিক অভিব্যক্তি সম্পাদন করতে ব্যবহৃত হতে পারে:

main(){                                                                                     

int i = 0;                                                                                  
int j = 1;                                                                                  
if(1)                                                                                       
    i=j,j+=1,printf("%d %d\n",i,j); // multiple statements are all executed                                                  
else                                                                                        
    printf("failed\n");                                                                     

}

আউটপুট: 1 2


কোনও একটি বিবৃতি থাকলে কাজ করে না break
ম্যাক্সিম মিখায়লভ

9
@ ম্যাক্সলাউনবয় কারণ breakএটি একটি বিবৃতি, এবং এই উত্তরটি প্রকাশের কথা বলছে।
নিডজেজেকোব

59

বিপর্যয়মূলক ফাংশন-যুক্তি ধরণের ঘোষণাগুলি এড়িয়ে চলুন

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

f(a,b,c,d,e){

তবে ধরুন dএটি একটি char, বা এমনকি একটি হওয়া দরকার int*। তাহলে তুমি ভুল যদি কোনও পরামিতি কোনও প্রকারের আগে থাকে তবে সেগুলি অবশ্যই হওয়া উচিত:

f(int a,int b,int c,int*d,int e){

কিন্তু অপেক্ষা করো! অকেজো চরিত্রগুলির এই বিপর্যয়কর বিস্ফোরণের চারপাশে একটি উপায় রয়েছে। এটা এইভাবেই চলে:

f(a,b,c,d,e) int *d; {

এমনকি mainযদি আপনার কমান্ড-লাইন আর্গুমেন্টগুলি ব্যবহার করার প্রয়োজন হয় তবে এটি একটি স্ট্যান্ডার্ড ডিক্লোরেশনও সংরক্ষণ করে :

main(c,v)char**v;{

এর চেয়ে কম দুটি বাইট

main(int c,char**v){

আমি এটি আবিষ্কার করে অবাক হয়েছি, যেহেতু আমি এতদিন পিপিসিজিতে এটির মুখোমুখি হই নি।


6
কেন পৃথিবীতে কাজ করে ??
নাথানিয়েল

30
স্পষ্টতই এটিকে কেএন্ডআর স্টাইল বলা হয় এবং এটি এএনএসআই সি এর এক দশক আগে।
ডেনিস

নোট করুন যে কেএন্ডআর বৈশিষ্ট্য এবং আরও নতুন ('99 বলুন) বৈশিষ্ট্যগুলি একসাথে নয় বা সম্ভবত সম্ভব নয় using আপনার সংকলক উপর নির্ভর করে।
ডিএমকেহে

5
@ ডিএমকেকে ঠিক বলেছেন। C99 অন্তর্নিহিত ইনটকে অনুমতি দেয় না, তাই আপনাকে ব্যবহার করতে হবে -std=gnu99এবং এখন আপনি পোর্টেবল নন। ক্লিপ-স্পোকে, আপনি এমনকি সেও "সি" কোড লিখছেন না, "Gnu99-C" করছেন। 'এখানে রাউন্ড আমরা বেশিরভাগই এটিকে উপেক্ষা করি, তবে আপনি যদি সংকলন নির্দিষ্ট করে কোড পোস্ট করেন তবে তা উল্লেখ করা ভাল। কখনও কখনও মানুষ আসলে কি ডাউনলোড করুন আমাদিগের এই প্রোগ্রামসমূহ চালানোর। :)
লুসার ড্রুগ

@ লেজারড্রোগ: আপনি -std=c89সেই পুরানো স্ট্যান্ডার্ড অনুযায়ী আপনার কোডটি সংকলন করতে জিসিসি বা ঝাঁকুনি বলতে ব্যবহার করতে পারেন , যা কেবলমাত্র একটি সতর্কতার সাথে অন্তর্নিহিত ইন্টিকে দেয়।
পিটার কর্ডেস

37

> = এবং <= এর পরিবর্তে তুলনামূলক মান শূন্যের উপরে চলে গেলে আপনি কেবলমাত্র পূর্ণসংখ্যা বিভাগ (/) ব্যবহার করতে পারেন যা একটি অক্ষর সংরক্ষণ করে। উদাহরণ স্বরূপ:

putchar(c/32&&126/c?c:46); //Prints the character, but if it is unprintable print "."

যা অবশ্যই এখনও সঙ্কুচিতযোগ্য, উদাহরণস্বরূপ কেবল> এবং ^ (কিছু ক্ষেত্রে লেখাকে && বা || এড়ানো একটি স্মার্ট উপায়) ব্যবহার করে।

putchar(c>31^c>126?c:46);

পূর্ণসংখ্যা বিভাগের কৌশল উদাহরণস্বরূপ কোনও সংখ্যা 100 এর চেয়ে কম কিনা তা সিদ্ধান্ত নিতে কার্যকর, কারণ এটি একটি অক্ষর সংরক্ষণ করে:

a<100 vs 99/a

উচ্চতর অগ্রাধিকার প্রয়োজন হয় যখন এটি ক্ষেত্রেও ভাল।


আপনি লিখতে পারেনputchar(c>31&c<127?c:46);
জিন এক্স

37

কিছু সংকলক, যেমন জিসিসি, আপনাকে বেসিক #includeএস, পরম এবং এর জন্য ফেরতের প্রকারগুলি বাদ দিতে দেয়main

নিম্নলিখিতটি একটি বৈধ C89 এবং C99 প্রোগ্রাম যা GCC এর সাথে সংকেত করে (সতর্কতা সহ):

main(i) { printf("%d", i); }

লক্ষ্য করুন যে #includestdio.h এর জন্য অনুপস্থিত, এর জন্য ফেরতের প্রকারটি mainঅনুপস্থিত এবং এর জন্য প্রকারের ঘোষণাটি iঅনুপস্থিত।


17
প্রযুক্তিগতভাবে এটি মান অনুসারে বৈধ নয় কারণ প্রধানটি শূন্য বা দুটি পরামিতি গ্রহণ করে, একটি নয়। যে কেউ কোড গল্ফ মধ্যে যত্নশীল না।
কনরাড বোরোস্কি

printf()প্রোটোটাইপ ছাড়াই কল করা (বা কোনও ভেরিয়ডিক ফাংশন) অনির্ধারিত আচরণের কারণ হয় । GCC ডিফল্টরূপে মান সি সংকলন করে না। আপনি যদি সিসি 89 মোড ( gcc -ansi -pedantic) বা সি 99 মোড ( gcc -std=c99 -pedantic) তে জিসিসি আবেদন করেন তবে কমপক্ষে পরবর্তী ক্ষেত্রে আপনি বেশ কয়েকটি অভিযোগ পেয়ে যাবেন।
নিস এনজিস্ট্রমে

@ নিসইঞ্জাস্ট্রাম: মূলধারার সি বাস্তবায়নের উপর কলিং কনভেনশনগুলি প্রোটোটাইপ ছাড়াই ভেরিয়াদিক ফাংশনগুলি কল করা নিরাপদ করে। সুতরাং বেশিরভাগ সি বাস্তবায়ন আচরণের সংজ্ঞা দেয়।
পিটার কর্ডস

29

টার্নারি শর্তসাপেক্ষ অপারেটরটি ?:প্রায়শই স্ট্যান্ড-ইন হিসাবে ব্যবহার করা যেতে পারে if- elseযথেষ্ট পরিমাণে সঞ্চয়ী হিসাবে বিবৃতি।

ভিন্ন C ++ সমতুল্য অপারেটর আনুষ্ঠানিকভাবে একটি lvalue দেয় না , কিন্তু কিছু কম্পাইলার (বিশেষতঃ জিসিসি) আপনি যা একটা চমৎকার বোনাস হিসেবে রয়েছে এটি দিয়ে পার পেতে, জানাতে হবে।


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

9
&&এবং ||এটি ব্যবহার করা যেতে পারে: if(x==3)f()আপনার পরামর্শের সাথে হয়ে যায় x==3?f():0এবং আরও উন্নত করা যেতে পারে x==3&&f()। তবে অপারেটরের অগ্রাধিকার সম্পর্কে সতর্কতা অবলম্বন করুন - যদি এটির f()সাথে প্রতিস্থাপন করা হয় y=1, তবে &&সমাধানটির জন্য অতিরিক্ত বন্ধনীগুলির একটি অতিরিক্ত সেট প্রয়োজন।
ugoren

1
আমি কখনই বুঝতে পারি নি যে ?:সিসি- র একটি লাভ হয়। আমি কি উত্পাদন কোড ব্যবহার করতে পারি? তোমার
জেফ Burdges

4
@ ইউগোরেন: x==3&&f()x^3||f()
fgrieu

@ ফগ্রিউ, হ্যাঁ, যদিও এটি এখানে ঠিক ঠিক বিষয় নয় ( এই উত্তরটি এর প্রস্তাব দেয়)।
ugoren

27

http://graphics.stanford.edu/~seander/bithacks.html

বিটস দুর্দান্ত।

~-x = x - 1
-~x = x + 1

তবে বিভিন্ন নজির সহ, এবং ++ এবং - এর মতো এক্স পরিবর্তন করবেন না। এছাড়াও আপনি এটি সত্যিই নির্দিষ্ট ক্ষেত্রে ব্যবহার করতে পারেন: 10 9 -10 এর চেয়ে কম orter

if(!(x&y)) x | y == x ^ y == x + y
if(!(~x&y)) x ^ y == x - y

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

x*y == x && y
if(x!=-y) x+y == x || y

এছাড়াও:

if(x>0 && y>0) x/y == x>=y   

5
শেষ টিপ ( (x/y) == (x>=y)) সত্যিই দরকারী।
এগারো

24

ল্যাম্বডাস (অপ্রয়োজনীয়) ব্যবহার করুন

পরিবর্তে

f(int*a,int*b){return*a>*b?1:-1;}
...
qsort(a,b,4,f);

বা (কেবলমাত্র জিসিসি)

qsort(a,b,4,({int L(int*a,int*b){a=*a>*b?1:-1;}L;}));

বা (ব্লক সমর্থন সহ এলএলভিএম)

qsort_b(a,b,4,^(const void*a,const void*b){return*(int*)a>*(int*)b?1:-1;});

কিছু চেষ্টা করুন

qsort(a,b,4,"\x8b\7+\6\xc3");

... যেখানে উদ্ধৃত স্ট্রিংটিতে আপনার "ল্যাম্বদা" ফাংশন (সমস্ত প্ল্যাটফর্ম এবিআইয়ের প্রয়োজনীয়তা অনুসারে) এর মেশিন ভাষার নির্দেশাবলী রয়েছে।

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

আপনার নিজের "ল্যাম্বদা" ফাংশনগুলি লিখতে শেখার একটি নিখুঁত উপায় হ'ল সিটিতে ফাংশনটি লিখুন, এটি সংকলন করুন, এর মতো কিছু দিয়ে এটি পরীক্ষা করুন objdump -Dএবং সংশ্লিষ্ট হেক্স কোডটি স্ট্রিংয়ে অনুলিপি করুন। উদাহরণ স্বরূপ,

int f(int*a, int*b){return *a-*b;}

... যখন gcc -Os -cএকটি লিনাক্স x86_64 টার্গেট দিয়ে সংকলন করা হয় এরকম কিছু তৈরি করে

0:   8b 07                   mov    (%rdi),%eax
2:   2b 06                   sub    (%rsi),%eax
4:   c3                      retq

জিএনইউ সিসি goto :

আপনি এই "ল্যাম্বডা ফাংশনগুলি" সরাসরি কল করতে পারেন তবে আপনি যে কোডটি কল করছেন তাতে যদি প্যারামিটার লাগে না এবং ফিরে না আসে তবে আপনি gotoকয়েকটি বাইট সংরক্ষণ করতে ব্যবহার করতে পারেন । পরিবর্তে তাই

((int(*)())L"ﻫ")();

বা (যদি আপনার পরিবেশে আরবি গ্লিফ না থাকে)

((int(*)())L"\xfeeb")();

চেষ্টা

goto*&L"ﻫ";

অথবা

goto*&L"\xfeeb";

এই উদাহরণে, eb fex86 মেশিনের মতো ভাষা languagefor(;;); এবং এমন কোনও কিছুর একটি সহজ উদাহরণ যা পরামিতি নেয় না এবং ফিরে আসবে না :-)

দেখা যাচ্ছে যে আপনি gotoএমন কোডিং করতে পারেন যা কলিং পিতামাতার কাছে ফিরে আসে।

#include<stdio.h>
int f(int a){
 if(!a)return 1;
 goto*&L"\xc3c031"; // return 0;
 return 2; // never gets here
}
int main(){
 printf("f(0)=%d f(1)=%d\n",f(0),f(1));
}

উপরের উদাহরণটি (এর সাথে লিনাক্স সংকলন এবং চালিত হতে পারে) gcc -O ) স্ট্যাক বিন্যাসের প্রতি সংবেদনশীল।

সম্পাদনা: আপনার সরঞ্জামচেনের উপর নির্ভর করে আপনাকে -zexecstackসংকলন পতাকা ব্যবহার করতে হতে পারে ।

যদি তা অবিলম্বে প্রকট হয় না, তবে এই উত্তরটি মূলত লোকেদের জন্যই লেখা হয়েছিল। আমি এটি পড়ার থেকে আরও ভাল বা খারাপ গল্ফিং বা প্রতিকূল মানসিক ফলাফলের জন্য কোনও দায় গ্রহণ করি না।


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

23

পয়েন্টারের পরিবর্তে কার্সার ব্যবহার করুন । brk()শুরুতে স্ন্যাগ করুন এবং এটি বেস-পয়েন্টার হিসাবে ব্যবহার করুন ।

char*m=brk();

তারপরে মেমরি অ্যাক্সেসের জন্য একটি # নির্ধারণ করুন।

#define M [m]

M*পূর্ণসংখ্যার জন্য প্রয়োগ একটি পোস্টফিক্স হয়ে যায় । (পুরানো একটি [এক্স] == এক্স [একটি] কৌশল)

তবে, আরও আছে! তারপরে আপনার পয়েন্টার আরগস এবং ম্যাক্রোগুলির চেয়ে কম ফাংশনগুলিতে রিটার্ন থাকতে পারে (বিশেষত যদি আপনি 'রিটার্ন' সংক্ষেপণ করেন):

f(x){return x M;} //implicit ints, but they work like pointers
#define f(x) (x M)

একটি পয়েন্টার থেকে কার্সার তৈরি করতে, আপনি বেস-পয়েন্টারটি বিয়োগ করে একটি ptrdiff_t উপার্জন করেন যা একটি অন্তর্নির্মিতভাবে কেটে যায়, ক্ষতিগুলি হ'ল ইয়ার বিজ।

char *p = sbrk(sizeof(whatever)) - m;
strcpy(m+p, "hello world");

এই কৌশলটি আমার জবাব ছাড়াই টাইপযুক্ত ল্যাম্বদা ক্যালকুলাসের জন্য একজন অনুবাদক লিখতে ব্যবহৃত হয় ।


21

ভেরিয়েবলের পরিবর্তে পরামিতিগুলি সংজ্ঞায়িত করুন।

f(x){int y=x+1;...}

f(x,y){y=x+1;...}

আপনাকে দ্বিতীয় প্যারামিটারটি পাস করার দরকার নেই।

এছাড়াও, প্রথম বন্ধনী সংরক্ষণের জন্য আপনি অপারেটর অগ্রাধিকার ব্যবহার করতে পারেন।
উদাহরণস্বরূপ, (x+y)*2হয়ে উঠতে পারে x+y<<1


বা ঠিক x+y*2, আরও একটি চর সংরক্ষণ করা।
ব্র্যাডেন সেরা

4
x+y*2অপারেটর অগ্রাধিকারের কারণে @ বি 1 কে মিউজিক এক নয়।
ugoren

ঠিক আছে, LOL এটি হবে এক্স + (y * 2)। আমাকে x+y<<1উদাহরণ হিসাবে স্থির করা হয়েছিল, ধরে নিলাম এটি মূল্যায়ন করা হচ্ছে x+(y<<1)এবং *2পরিবর্তে প্রস্তাবিত । আমি জানতাম না যে বিটশিফ্ট অপারেশনগুলি যেমন মূল্যায়ন করা হয়েছিল(x+y)<<2
ব্র্যাডেন বেস্ট

20

সাধারণত যেহেতু EOF == -1, ইওএফটি পরীক্ষা করতে বিটওয়াইস নট অপারেটরটি ব্যবহার করুন: while(~(c=getchar()))বা while(c=getchar()+1)প্রতিটি জায়গায় সি এর মান সংশোধন করুন


1
আমি সি-কে যথেষ্ট পরিমাণে চিনি না, তবে while(1+c=getchar())কাজ করবে না ?
4uʎs 4'15

6
@ No.uʎs। সংযোজন অপারেটরের +চেয়ে সংযোজন অপারেটরের উচ্চতর অগ্রাধিকার রয়েছে =, সুতরাং 1+c=getchar()এটি সমান (1+c)=getchar(), যা সংকলন করে না কারণ (1+c)একটি মূল্য নেই।
#HongKongInd dependence

19

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

নিম্নলিখিত উদাহরণটি ধরুন:

if (t()) a = b, b = 0;  /* 15 chars */

স্বাভাবিক গল্ফিং পদ্ধতির সাথে এটি প্রতিস্থাপন করা ifহয় &&, তবে কমা অপারেটরের কম অগ্রাধিকারের কারণে আপনার একটি অতিরিক্ত জুটি বন্ধনী প্রয়োজন:

t() && (a = b, b = 0);  /* still 15 chars */

টেরিনারি অপারেটরের মাঝের অংশটির প্রথম বন্ধনী প্রয়োজন নেই, যদিও:

t() ? a = b, b = 0 : 0;  /* 14 chars */

অনুরূপ মন্তব্য অ্যারে সাবস্ক্রিপ্টগুলিতে প্রযোজ্য।


7
এই উদাহরণে, b-=a=bআরও খাটো হয়। ?:কৌতুক, এখনো সহায়ক -=কারণ এছাড়াও কম পক্ষপাত আছে।
ugoren

ভাল যুক্তি; আমার উদাহরণটি অযথা জটিল ছিল।
ব্রেডবক্স

জন্য: আরেকটি বিষয় যে কখনো কখনো আপনি শর্ত টুসকি করতে চান x>0||(y=3), x>0?0:(y=3)বেহুদা, কিন্তু x<1?y=3:0পেশা আছে।
ugoren

ঝনঝন এবং জিসিসি উভয়ই ত্রিনিয়ারীতে খালি সত্যিকারের ক্ষেত্রে অনুমতি দেয় । বাদ দেওয়া থাকলে এর মান হ'ল শর্তের মান। উদাহরণস্বরূপ,x>5?:y=1
ক্রিস উজাদাবিনিস

19

আপনার কোডের যে কোনও অংশ যা বহুবার পুনরাবৃত্তি করে তা হ'ল প্রাক-প্রসেসরের সাথে প্রতিস্থাপনের প্রার্থী।

#define R return

যদি আপনার কোডটি কয়েকটি কার্যের চেয়ে বেশি জড়িত থাকে তবে এটি একটি সাধারণ ব্যবহারের কেস। অন্যান্য লম্বাটে কিওয়ার্ডগুলি অনুসন্ধানের মত while, double, switch, এবংcase এছাড়াও প্রার্থী হয়; পাশাপাশি আপনার কোডে মূর্তিযুক্ত যে কোনও কিছু।

আমি সাধারণত এই উদ্দেশ্যে বড় হাতের অক্ষর সংরক্ষণ করি।


1
একটি সংক্ষিপ্ত প্রতিস্থাপন হবে -DR=return। মনে রাখবেন যে আপনি যদি নির্দিষ্ট অক্ষরগুলি অন্তর্ভুক্ত করেন তবে সংজ্ঞায়নের চারপাশে একক বা ডাবল উদ্ধৃতি থাকা প্রয়োজনীয় হয়ে উঠতে পারে -DP='puts("hello")'

15

যদি আপনার প্রোগ্রামটি প্রতিটি পদক্ষেপের ভিত্তিতে একটিতে পড়তে বা লিখতে থাকে তবে সর্বদা getchar () এবং putchar () এর পরিবর্তে পঠন এবং লেখার ফাংশনটি ব্যবহার করার চেষ্টা করুন ।

উদাহরণ ( স্ট্যান্ডআউটকে বিপরীত করুন এবং স্থান )

main(_){write(read(0,&_,1)&&main());}

অনুশীলন: এখানে একটি ভাল স্কোর পেতে এই কৌশলটি ব্যবহার করুন


প্রতিটি পদক্ষেপের ভিত্তিতে আপনি কী বোঝাতে চান ?
কেসি

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

জোয় ঠিকই বলেছে, আমি একই কথা বোঝাতে চাইছি, দুঃখিত আমি আজ অবধি আমার ইনবক্সটি পরীক্ষা করে দেখিনি।
কুইসোটিক

8
যে স্ট্যাক ম্যানিপুলেশন চমত্কার।
আন্দ্রে বিওনদো

14

বিপরীত লুপগুলি

আপনি যদি পারেন তবে প্রতিস্থাপনের চেষ্টা করুন

for(int i=0;i<n;i++){...}

সঙ্গে

for(int i=n;i--;){...}

13

আপনার যদি কখনও একক নিউলাইন অক্ষর ( \n) আউটপুট করতে হয় তবে ব্যবহার করবেন না putchar(10), ব্যবহার করুন puts("")


12

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

উদাহরণ:

close(fd);foo=0;   →  foo=close(fd);    /* saves two bytes */
putchar(c);bar=0;  →  bar=!putchar(c);  /* saves one byte  */

12

ফেরতের পরিবর্তে বরাদ্দ করুন।

এটি সত্যিকারের স্ট্যান্ডার্ড সি নয়, তবে প্রতিটি সংকলক এবং সিপিইউ নিয়ে কাজ করে যা আমি জানি:

int sqr(int a){return a*a;}

একই প্রভাব আছে:

int sqr(int a){a*=a;}

কারণ প্রথম যুক্তিটি একই সিপিইউতে রিটার্ন মান হিসাবে সঞ্চিত থাকে।

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

এক্স-ম্যাক্রো

আর একটি দরকারী বৈশিষ্ট্য: এক্স-ম্যাক্রোস যখন আপনাকে ভেরিয়েবলগুলির একটি তালিকা থাকে এবং আপনাকে কিছু ক্রিয়াকলাপ করতে হবে যা এতে সমস্তগুলিকে জড়িত করে আপনাকে সাহায্য করতে পারে:

https://en.wikipedia.org/wiki/X_Macro


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

3
আপনি ঠিক বলেছেন, এটি অপরিজ্ঞাত আচরণ, এটি সংকলক এবং আর্কিটেকচারের উপরও নির্ভর করে, আমি সাধারণত এই কৌশলটি ব্যবহার করে কোনও উত্তর পোস্ট করার আগে x86 এবং আর্মভি 7-তে জিসিসি দিয়ে পরীক্ষা করি। এবং অবশ্যই যদি আপনি অপ্টিমাইজেশন সক্ষম করেন তবে যে কোনও স্মার্ট সংকলক কেবল অপ্রয়োজনীয় গুণকে মুছে ফেলবে।
জিবি

3
আমি জিসিসির সাথে এই কাজটি দেখেছি কিন্তু অন্যদের সাথে নয়
অ্যালবার্ট রেনশওয়া

1
@ গ্যাসপা 79৯: জিসিসি -O0সর্বদা রিটার্ন-ভ্যালু রেজিষ্টারে এক্সপ্রেশনগুলি মূল্যায়ন করতে পছন্দ করে। আমি x86, এআরএম এবং এমআইপিএস দেখেছি কমপক্ষে ( জিসিপি . godbolt.org- এ ), এবং জিসিসি এটি করার উপায় থেকে বেরিয়ে গেছে বলে মনে হচ্ছে -O0। তবে মনে রাখবেন যদি এই সুবিধা গ্রহণ, আপনি প্রোগ্রামিং করছি ভাষা gcc -O0, না সি না সি হিসাবে, এবং আপনি সেই অনুযায়ী আপনার উত্তরের লেবেলটির উচিত, । এটি -O0ডিবাগ মোড ব্যতীত অন্য কোনও অপ্টিমাইজেশন স্তরে ব্যর্থ হয় এবং ঝাঁকুনি আইআইআরসি দিয়ে কাজ করে না।
পিটার কর্ডস

11
  1. *aপরিবর্তে ব্যবহার করুনa[0]অ্যারের প্রথম উপাদানটি অ্যাক্সেস করার ।

  2. রিলেশনাল অপারেটর ( !=, >ইত্যাদি) দেয় 0বা দেয় 1। কিনা শর্ত সত্য বা মিথ্যা উপর নির্ভর করে বিভিন্ন অফসেট দিতে গাণিতিক অপারেটর সাথে ব্যবহার করুন, a[1+2*(i<3)]অ্যাক্সেস হবে a[1]যদি i >= 3এবং a[3]অন্যথায়।


11
a[i<3?3:1]এর চেয়ে কম দুটি চরিত্র a[1+2*(i<3)]
রেটো কোরাাদি

10

আপনি আইওসিসি আর্কাইভগুলিতে নজর রাখতে পারেন (আন্তর্জাতিক অবরুদ্ধ সি কোড প্রতিযোগিতা)।

একটি উল্লেখযোগ্য কৌশল # ডেফাইন ম্যাক্রোগুলি যার সম্প্রসারণে ভারসাম্যহীন ব্রেস / প্রথম বন্ধনী রয়েছে has

#define P printf(

16
মেলে না এমন প্রথম বন্ধনীগুলির নিজের কোনও মূল্য নেই। পয়েন্টটি যতটা সম্ভব পুনরাবৃত্তি প্যাটার্নটি নির্ধারণ করা। সাথে আপনি আরও যেতে চাইবেন #define P;printf(
ugoren

কিভাবে এই সংক্ষিপ্ত বাইট গণনা? সম্ভবত একটি উদাহরণ প্রদান?
সাইয়েস

2
@ কিয়েস উদাহরণস্বরূপ এই উত্তরটি দেখুন
জোনাথন ফ্রেচ

8

for(int i=0;i<n;i++){a(i);b(i);} কয়েকটি উপায়ে খাটো করা যায়:

for(int i=0;i<n;){a(i);b(i++);}লুপে ++সর্বশেষে স্থানান্তরিত করার জন্য -1i

for(int i=0;i<n;b(i++))a(i); ব্রেসগুলি মুছে ফেলা, প্রধান লুপের উপরে এবং বাইরে একটি বিবৃতি ছাড়া সমস্ত সরানোর জন্য আরও 3


কমা অপারেটর ব্যবহার কিছু ক্ষেত্রে ব্রেস এড়ানোর অন্য উপায়।
পিটার কর্ডেস

8

ফাংশনাল যান!

যদি আপনি একই স্বাক্ষর সহ একক এক্সপ্রেশন হিসাবে সংজ্ঞায়িত করে সাধারণ ফাংশনগুলিতে আপনার সমস্যাটিকে হ্রাস করতে পারেন তবে #define r returnকোনও ফাংশন সংজ্ঞায়িত করার জন্য আপনি প্রায় সমস্ত বয়লারপ্লেটের চেয়ে ভাল এবং ফ্যাক্টর আউট করতে পারেন ।

#define D(f,...)f(x){return __VA_ARGS__;}
D(f,x+2)
D(g,4*x-4)
D(main,g(4))

প্রোগ্রামের ফলাফলটি তার স্থিতির মান ওএস এ ফিরে আসে বা শেল বা আইডিই নিয়ন্ত্রণ করে।

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

#define D(f,b)f(x){return b;}

7
  1. scanf("%*d ");ডামি ইনপুট পড়তে ব্যবহার করুন। (যদি পরবর্তী প্রোগ্রামে ইনপুট অর্থহীন হয়) তবে scanf("%d",&t);আপনাকে যেখানে ভেরিয়েবল টি ঘোষণা করতে হবে তার চেয়ে এটি ছোট orter

  2. ইন্টার অ্যারে অক্ষর সংরক্ষণ করা অক্ষরের অ্যারের চেয়ে অনেক ভাল। উদাহরণ।

    s[],t;main(c){for(scanf("%*d ");~(c=getchar());s[t++]=c)putchar(s[t]);}


2
প্রকৃতপক্ষে, আমি %*dকেবল scanf("%[^\n]%*c",str);
গল্ফেই

6

একটি অক্ষর মুদ্রণ করুন তারপরে ক্যারিজ রিটার্নের পরিবর্তে:

printf("%c\n",c);

অথবা

putchar(c);putchar('\n'); // or its ascii value, whatever!

কেবল গ হিসাবে একটি int হিসাবে ঘোষণা করুন এবং:

puts(&c);

9
এটি সম্ভবত উল্লেখ করার মতো যে এটি সামান্য-এন্ডিয়ান আর্কিটেকচারের উপর নির্ভর করে। যদি সি একটি বড়-এডিয়ান ইন্ট হয় তবে আপনি কেবল গাড়ীর রিটার্ন পাবেন। (অন্যদিকে, সি যদি চর হয়, তবে আপনি গাড়ীর ফেরার পরিবর্তে এলোমেলো আবর্জনা পেতে পারেন))
ব্রেডবক্স

@ ব্রেডবক্স হ্যাঁ, আপনি পুরোপুরি ঠিক বলেছেন; আমি কেবল সম্পাদনা করেছি: সর্বশেষ অংশটি সি হিসাবে ব্যবহার করা উচিত (যা প্রায়শই এরূপে ঘোষণা করা সহজ)।
মোয়ালা

puts(&c)সত্যিই কি কাজ করে? এটি অকারণে বাতিল হবে না।
16:40

1
@ এসোলেংফ্রুট 32-বিট ইনট সহ লিটল এন্ডিয়ানে, একটি ইনট্রি 0 ≤ সি <256 বাইট সিকোয়েন্স সি 0 0 0 হিসাবে সংরক্ষণ করা হয় । এর ঠিকানার ঠিকানা হিসাবে অনুবাদ করার সময় char *আমরা একটি সিঙ্গলটন স্ট্রিং দেখতে পাই: অক্ষর সি , একটি নাল বাইট অনুসরণ করে।
ডেনিস

6

ব্যবহার asprintf() আপনাকে সুস্পষ্ট বরাদ্দ এবং স্ট্রিং ওরফে দৈর্ঘ্য পরিমাপ সংরক্ষণchar* ! কোড গল্ফিংয়ের জন্য এটি খুব বেশি কার্যকর না হলেও চরের অ্যারে দিয়ে দৈনন্দিন কাজকে সহজ করে দেয়। একবিংশ শতাব্দী সি তে আরও কিছু ভাল পরামর্শ রয়েছে ।

ব্যবহারের উদাহরণ:

#define _GNU_SOURCE
#include <stdio.h>

int main(int argc, char** argv) {
  char* foo;
  asprintf(&foo, "%s", argv[1]);
  printf("%s",foo);
}

6

import যদি আপনার হয়

প্রথম উত্তরে উল্লিখিত হিসাবে , কিছু সংকলক (উল্লেখযোগ্যভাবে, জিসিসি এবং ঝনঝন) আপনাকে #includeস্ট্যান্ডার্ড লাইব্রেরি ফাংশনগুলির জন্য বাদ দিতে দেয় let

এমনকি যদি আপনি শুধু সরাতে পারবেন না #include, সেখানে হতে পারে অন্য কোন উপায়ে এটা এড়ানোর জন্য , কিন্তু যে সবসময় ব্যবহারিক বা বিশেষ করে golfy নয়।

বাকি ক্ষেত্রে, আপনি বাইট সংরক্ষণ করার #import<header file>পরিবর্তে ব্যবহার করতে পারেন #include<header file>। এটি একটি জিএনইউ এক্সটেনশন এবং এটিকে অবহেলিত হিসাবে বিবেচনা করা হয় তবে এটি কমপক্ষে জিসিসি 4.8, জিসিসি 5.1 এবং ঝাঁকুনি 3.7 এ কাজ করে।


6

cpow()পরিবর্তে চেষ্টা করুনcos()

পরিবর্তে

double y=cos(M_PI*2*x);

কিছু চেষ্টা করুন

double y=cpow(-1,x*2);

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

\ কোস 2 \ পাই x + জ \ পাপ 2 \ পাই x = ই ^ {জ 2 \ পাই x} = ই ^ {জে \ পাই 2x} = (- 1) ^ {2x}

এই ধরণের কৌশলটি হ্রাস করতে ব্যবহার করা যেতে পারে

double y=cpow(-1,x/2);

মধ্যে

double y=cpow(1i,x);

কারণ (-1) ^ অর্থাত \ frac {এক্স} {2} = ঞ ^ {অর্থাত \ frac {2x} {2}} = ঞ ^ x এর


5

এখানে আমি আমার সুবিধার জন্য কয়েকটি টিপস ব্যবহার করেছি। আমি নির্লজ্জভাবে এগুলি অন্যের কাছ থেকে চুরি করেছি, সুতরাং আমাকে ছাড়া অন্য কারও কাছে কৃতিত্ব:

ফাংশন কলগুলির সাথে অ্যাসাইনমেন্ট একত্রিত করুন

এর পরিবর্তে:

r = /* Some random expression */
printf("%d", r);

এটা কর:

printf("%d", r = /* Some random expression */);

একসাথে একাধিক ভেরিয়েবল সূচনা করুন (যখন সম্ভব)

এর পরিবর্তে:

for(i=0,j=0;...;...){ /* ... */ }

এটা কর:

for(i=j=0;...;...){ /* ... */ }

শূন্য / ননজারো মানগুলি সঙ্কুচিত করুন

এটি একটি ঝরঝরে কৌশল আমি এখানকার কারও কাছ থেকে গ্রহণ করেছি (মনে রাখবেন না কে, দুঃখিত)। যখন আপনার একটি পূর্ণসংখ্যার মান হয় এবং আপনার এটি 1 বা 0 টিতে সঙ্কুচিত হওয়া দরকার, আপনি খুব !!সহজেই এটি ব্যবহার করতে পারেন। এটি অন্যান্য বিকল্পের মতো কখনও কখনও সুবিধাজনক ?:

এই পরিস্থিতি নিন:

n=2*n+isupper(s[j])?1:0; /* 24 */

পরিবর্তে আপনি এটি করতে পারেন:

n=n*2+!!isupper(s[j]); /* 22 */

আরেকটি উদাহরণ:

r=R+(memcmp(b+6,"---",3)?R:0); /* 30 */

এটি আবার লিখতে পারে:

r=R+R*!!memcmp(b+6,"---",3)); /* 29 */

1
হতে পারেR*-~!!mxxxx
l4m2

5

মৌলিক যৌক্তিক সমতাগুলি জানা একটি দম্পতি বাইট সংরক্ষণ করতে সক্ষম হতে পারে। উদাহরণস্বরূপ, পরিবর্তে if (!(a&&b)){}ডি মরগান আইন ব্যবহার করার চেষ্টা করুন if (!a||!b){}। বিটওয়াইজ ফাংশনগুলিতে একই প্রযোজ্য: পরিবর্তে ~(a|b)করণীয় ~a&~b


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