double d;_;f(double(*x)(double)){d=x(0.9247);_=*(int*)&d%12;puts((char*[]){"acosh","sinh","asinh","atanh","tan","cosh","asin","sin","cos","atan","tanh","acos"}[_<0?-_:_]);}
এটি অনলাইন চেষ্টা করুন!
পুরানো তবে শীতল: সি (জিসিসি) , 194 বাইট
double d;_;f(double(*x)(double)){char n[]="asinhacoshatanh";d=x(0.9247);_=*(int*)&d%12;_=(_<0?-_:_);n[(int[]){10,5,5,0,14,10,4,4,9,14,0,9}[_]]=0;puts(n+(int[]){5,1,0,10,11,6,0,1,6,10,11,5}[_]);}
এটি অনলাইন চেষ্টা করুন!
-lm
Tio মধ্যে সুইচ নিছক পরীক্ষার জন্যে। আপনি যদি
স্ট্যান্ডার্ড ট্রিগ ফাংশনের একটি নিখুঁত বাস্তবায়ন লিখতে পারেন তবে সঠিক উত্তরটি পাবেন।
ব্যাখ্যা
ধারণাটি এমন কিছু ইনপুট মান সন্ধান করা ছিল যে আমি যখন ট্রিগার ফাংশনগুলির প্রতিটি ফলাফলের পূর্ণসংখ্যা হিসাবে ব্যাখ্যা করি তখন তাদের পৃথক অনুসারীগুলি মডিউল ১২ থাকে This এটি তাদের অ্যারে সূচক হিসাবে ব্যবহার করার অনুমতি দেবে।
এই জাতীয় ইনপুট মানটি খুঁজতে আমি নিম্নলিখিত স্নিপেট লিখেছিলাম:
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
// Names of trig functions
char *names[12] = {"sin","cos","tan","asin","acos","atan","sinh","cosh","tanh","asinh","acosh","atanh"};
// Pre-computed values of trig functions
double data[12] = {0};
#define ABS(X) ((X) > 0 ? (X) : -(X))
// Performs the "interpret as abs int and modulo by" operation on x and i
int tmod(double x, int i) {
return ABS((*(int*)&x)%i);
}
// Tests whether m produces unique divisors of each trig function
// If it does, it returns m, otherwise it returns -1
int test(int m) {
int i,j;
int h[12] = {0}; // stores the modulos
// Load the values
for (i = 0; i < 12; ++i)
h[i] = tmod(data[i],m);
// Check for duplicates
for (i = 0; i < 12; ++i)
for (j = 0; j < i; ++j)
if (h[i] == h[j])
return -1;
return m;
}
// Prints a nicely formatted table of results
#define TEST(val,i) printf("Value: %9f\n\tsin \tcos \ttan \n \t%9f\t%9f\t%9f\na \t%9f\t%9f\t%9f\n h\t%9f\t%9f\t%9f\nah\t%9f\t%9f\t%9f\n\n\tsin \tcos \ttan \n \t%9d\t%9d\t%9d\na \t%9d\t%9d\t%9d\n h\t%9d\t%9d\t%9d\nah\t%9d\t%9d\t%9d\n\n",\
val,\
sin(val), cos(val), tan(val), \
asin(val), acos(val), atan(val),\
sinh(val), cosh(val), tanh(val),\
asinh(val), acosh(val), atanh(val),\
tmod(sin(val),i), tmod(cos(val),i), tmod(tan(val),i), \
tmod(asin(val),i), tmod(acos(val),i), tmod(atan(val),i),\
tmod(sinh(val),i), tmod(cosh(val),i), tmod(tanh(val),i),\
tmod(asinh(val),i), tmod(acosh(val),i), tmod(atanh(val),i))
// Initializes the data array to the trig functions evaluated at val
void initdata(double val) {
data[0] = sin(val);
data[1] = cos(val);
data[2] = tan(val);
data[3] = asin(val);
data[4] = acos(val);
data[5] = atan(val);
data[6] = sinh(val);
data[7] = cosh(val);
data[8] = tanh(val);
data[9] = asinh(val);
data[10] = acosh(val);
data[11] = atanh(val);
}
int main(int argc, char *argv[]) {
srand(time(0));
// Loop until we only get 0->11
for (;;) {
// Generate a random double near 1.0 but less than it
// (experimentally this produced good results)
double val = 1.0 - ((double)(((rand()%1000)+1)))/10000.0;
initdata(val);
int i = 0;
int m;
// Find the smallest m that works
do {
m = test(++i);
} while (m < 0 && i < 15);
// We got there!
if (m == 12) {
TEST(val,m);
break;
}
}
return 0;
}
আপনি যদি এটি চালনা করেন (যা -lm দিয়ে সংকলন করা প্রয়োজন) এটি থুতু হবে যে 0.9247 এর মান সহ আপনি অনন্য মান পাবেন।
পরবর্তী আমি পূর্ণসংখ্যার হিসাবে পুনরায় স্থাপন করেছি, 12 দ্বারা মডুলো প্রয়োগ করেছি এবং পরম মান নিয়েছি। এটি প্রতিটি ফাংশনকে একটি সূচক দিয়েছে। তারা ছিল (0 -> 11 থেকে): আকোশ, সিনাহ, আসিনহ, আতানহ, তন, কোশ, আসিন, পাপ, কোস, আতান, তানহ, একোস।
এখন আমি কেবল একটি স্ট্রিংয়ের অ্যারেতে সূচি রাখতে পারি, তবে নামগুলি খুব দীর্ঘ এবং খুব অনুরূপ, সুতরাং পরিবর্তে আমি সেগুলি স্ট্রিংয়ের টুকরো থেকে বের করে আনতে পারি।
এটি করার জন্য আমি "asinhacoshatanh" এবং দুটি অ্যারে স্ট্রিং তৈরি করি। প্রথম অ্যারেটি শূন্যের কোন অক্ষরকে নাল টার্মিনেটরে সেট করতে হবে তা বোঝায়, যখন দ্বিতীয়টি সূচিত করে যে স্ট্রিংয়ের অক্ষরটি প্রথম হওয়া উচিত। এই অ্যারেগুলিতে রয়েছে: 10,5,5,0,14,10,4,4,9,14,0,9 এবং 5,1,0,10,11,6,0,1,6,10,11, যথাক্রমে 5।
পরিশেষে এটি সি তে পুনরায় ব্যাখ্যা ব্যাখ্যার অ্যালগরিদম দক্ষতার সাথে প্রয়োগ করার বিষয় ছিল দুঃখজনকভাবে আমাকে ডাবল টাইপটি ব্যবহার করতে হয়েছিল এবং ঠিক double
তিনটি ব্যবহারের সাথে কেবল মাত্র তিনটি #define D double\nDDD
অক্ষর দ্বারা তিনবার ব্যবহার করা তত দ্রুত ছিল । ফলাফল উপরে, একটি বিবরণ নীচে:
double d;_; // declare d as a double and _ as an int
f(double(*x)(double)){ // f takes a function from double to double
char n[]="asinhacoshatanh"; // n is the string we will manipulate
int a[]={10,5,5,0,14,10,4,4,9,14,0,9}; // a is the truncation index
int b[]={5,1,0,10,11,6,0,1,6,10,11,5}; // b is the start index
d=x(0.9247); // d is the value of x at 0.9247
_=*(int*)&d%12; // _ is the remainder of reinterpreting d as an int and dividing by 12
_=(_<0?-_:_); // make _ non-negative
n[a[_]]=0; // truncate the string
puts(n+b[_]);} // print the string starting from the correct location
সম্পাদনা: দুর্ভাগ্যক্রমে কেবল একটি কাঁচা অ্যারে ব্যবহার করা আসলে খাটো, সুতরাং কোডটি আরও সহজ হয়ে যায়। তবুও স্ট্রিং স্লাইসিং মজাদার ছিল। তত্ত্বের মধ্যে একটি উপযুক্ত যুক্তি আসলে কিছুটা গণিতের সাথে ডান টুকরোগুলি নিয়ে আসে।