ट्यूनिंग स्ट्रिंग्स


9

कार्य

नोट को निर्धारित करने के लिए एक प्रोग्राम लिखें, साथ ही कितने टेंट से बाहर निकलते हैं, एक दिए गए फ्रिक्वेंसी से जुड़े स्ट्रिंग के नीचे और एक दिए गए बिंदु पर दबाया जाता है।

सादगी के लिए, मान लें कि ध्वनि की आवृत्ति और स्ट्रिंग की लंबाई जहां इसे दबाया गया है, उसके विपरीत आनुपातिक हैं।

नोट: यह कार्य केवल मूल स्वर में है, न कि ओवरटोन / अन्य हार्मोनिक्स के साथ।

इनपुट

आपके कार्यक्रम को दो टुकड़े दिए गए हैं:

  • मनमानी लंबाई की एक स्ट्रिंग, जो प्रश्न में स्ट्रिंग का प्रतिनिधित्व करती है। यह स्ट्रिंग एक एक्स के साथ चिह्नित की जाएगी जहां स्ट्रिंग को नीचे रखना है।

    [-----] is a string divided in six sections (five divisions).
    [--X--] is a string pressed at the exact center of the string.
    [X----] is a string pressed at 1/6 the length of the string. (Length used is 5/6)
    [-X--] is a string pressed at 2/5 of the length of the string. (Length used is 3/5)
    

    मान लें कि स्ट्रिंग के भाग के दाईं ओर नोट का उपयोग किया गया है X

  • एक संख्या (जरूरी नहीं कि एक पूर्णांक), उस आवृत्ति को दर्शाता है जिस पर स्ट्रिंग को ट्यून किया जाता है। इस संख्या की सटीकता दशमलव के पिछले चार अंकों में होगी।

यह माना जा सकता है कि पारित आवृत्तियों 10 Hzऔर के बीच झूठ होगा40000 Hz

इनपुट को आपकी पसंद के प्रारूप में पास किया जा सकता है। कृपया निर्दिष्ट करें कि आपके उत्तर में इनपुट को आपके प्रोग्राम में कैसे स्वीकार किया जाता है।

उत्पादन

आपके कार्यक्रम को बारह-स्वर समान स्वभाव ट्यूनिंग प्रणाली में निकटतम नोट * दोनों का उत्पादन करना चाहिए, और निकटतम नोट से सेंट की संख्या जो स्ट्रिंग द्वारा दर्शाया गया ध्वनि है (निकटतम प्रतिशत तक पहुंच जाएगी)।

+nसेंट का उपयोग nनोट के ऊपर / ऊपर तेज सेंट को दर्शाने के लिए किया जाना चाहिए-n नोट के नीचे / फ्लैट के लिए ।

नोट को वैज्ञानिक पिच अंकन में आउटपुट किया जाना चाहिए। मान लें कि A4 को ट्यून किया गया है 440Hz। फ्लैट / तेज नोटों के लिए b और # का उपयोग करें। नोट: या तो तेज या फ्लैट इस्तेमाल किया जा सकता है। नोट के लिए पर 466.16Hz, या तो A#याBb टिप्पणी के लिए outputted जा सकता है।

आउटपुट का प्रारूप आपके ऊपर है, जब तक कि आउटपुट में जानकारी के केवल दो पहले से निर्दिष्ट टुकड़े होते हैं (यानी हर एक संभावित आउटपुट को प्रिंट करने की अनुमति नहीं है)।

* निकटतम नोट उस नोट को संदर्भित करता है जो इनपुट द्वारा निरूपित ध्वनि के सबसे करीब है, सेंट की संख्या में मापा जाता है (इसलिए, वह नोट जो 50 centsध्वनि के भीतर है)। यदि ध्वनि है50 cents दो अलग-अलग नोटों (राउंडिंग के बाद) से दूर है, तो दोनों में से कोई भी नोट आउटपुट हो सकता है।

उदाहरण

आपका कार्यक्रम सभी मामलों के लिए काम करना चाहिए, न कि केवल निम्नलिखित उदाहरणों के लिए।

Output             Input Frequency   Input String
A4,  +0  cents     220               [-----X-----]
A5,  +0  cents     220               [--------X--]
D5,  -2  cents     440               [--X--------]
B4,  -49 cents     440               [X----------]
A#4, +19 cents*    314.1592          [X-]
Eb9, +8  cents*    400               [-----------------------X]
Eb11,+8  cents*    100               [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------X]
D#1, +49 cents*    10                [--X]
A0,  -11 cents     11.7103           [---X--]

* या तो तेज या फ्लैट आउटपुट किया जा सकता था।

संभावित रूप से सहायक लिंक

ये है इतना कम जवाब जीतता है।


मुझे लगता है कि आपके उदाहरण कुछ असंगत हैं: पहले एक [--X--]के अनुसार स्ट्रिंग को उस विभाजन के बीच में दबाया जाता है जहां xरखा गया है, जबकि [-X--]इस तर्क का पालन करते समय अंतिम 3/8 (2/5 नहीं) पर होगा। या मैं कुछ गलत समझ रहा हूं?
दोष

पिछले एक के लिए @flawr [-X--], स्ट्रिंग को 4 स्थानों (और इसलिए 5 भागों में) में विभाजित किया गया है, और इन विभाजनों में से दूसरे पर दबाया गया है। इस प्रकार, इसे दबाया जाता है 2/5, और उपयोग की जाने वाली लंबाई होती है 3/5
es1024

आह ठीक है अब मैं देखता हूं, इसलिए प्रत्येक -मूल रूप से विभाजनों की स्थिति का प्रतिनिधित्व करता है, समझाने के लिए धन्यवाद!
दोष

जवाबों:


1

बीबीसी बेसिक, 161 #

  REM get frequency and string. Store length of string in n for later.
  INPUT f,s$
  n=LEN(s$)

  REM store floating-point value of note in semitones above (C0-0.5). Store integer value in n% (offset effectively means it will be rounded not truncated.)
  n=LN(f*(n-1)/(n-INSTR(s$,"X"))/15.8861)/LN(2)*12
  n%=n

  REM format printing to whole numbers only
  @%=2^17

  REM Output note name and octave. Output cents (discrepancy between n and n%, minus the offset of 0.5)
  PRINT MID$("C C#D D#E F F#G G#A A#B ",n%MOD12*2+1,2);INT(n/12)'(n-0.5-n%)*100'

स्कोर टिप्पणियों को छोड़कर। अभी तक गोल्फ नहीं हुआ।

उत्पादन

दो लंबे लोगों को छोड़कर सभी परीक्षण मामलों पर सही ढंग से करता है। के लिए Eb9यह लगता है एक पानी का छींटा परीक्षण मामले से लापता है: वहाँ 22 कर रहे हैं -और एक Xहै, जो 24 बराबर टुकड़ों में स्ट्रिंग बिताते हैं। मेरी मैनुअल गणना के अनुसार, यह 9600 हर्ट्ज है, जो कि डी 9 से 37 सेंटीमीटर ऊपर है। यह वही है जो मेरा प्रोग्राम आउटपुट करता है। अगर मैं एक और डैश जोड़ूं तो मुझे Eb9 + 8 सेंट मिलते हैं। दुर्भाग्य से बीबीसी बेसिक 255 से अधिक वर्णों को संभाल नहीं सकता है, इसलिए Eb11मामला त्रुटि देता है।

यहां छवि विवरण दर्ज करें


3

सी, 179

main(n,d){float f;scanf("%*[^X]%nX%*[-]%n]%f",&n,&d,&f);f=log(f*d/(d-n))*17.3123-57.376;n=d=f+.5;n=n%12*7+784;printf("%c%d%c,%+2.0f cents\n",n/12,(d+9)/12,n%12/7*3+32,(f-d)*100);}

अपने आप ही एक लाइन पर एससीआई तस्वीर और एक अलग लाइन पर आवृत्ति प्राप्त करता है।

कुछ वर्ण जादू संख्या की सटीकता को कम करके छोड़ा जा सकता है 17.3123और57.376

गोल्फिंग के बिना, कार्यक्रम इस तरह दिखता है:

main(n,d)
{
    float f; // 'float' and '%f' better than 'double' and '%lf'

    scanf("%*[^X]%nX%*[-]%n]%f", &n, &d, &f);
    // n is the number of chars before 'X'
    // d is the number of chars before ']'
    // f is the frequency

    // Calculate the tuned frequency
    f = f * d / (d - n);

    // Convert the frequency to logarithmic scale, relative to pitch A0
    f=log(f)*17.3123-57.376;
    // alternatively: f = log2(f / (440 / 16)) * 12;

    // Round to nearest integer
    n=d=f+.5;

    // Calculate the note name ('A', 'B', etc), multipled by 12 for convenience
    n=n%12*7+784;

    printf("%c%d%c,%+2.0f cents\n", // output example: B4 ,-49 cents
        n/12,        // note name
        (d+9)/12,    // octave number
        n%12/7*3+32, // if n%12 is large enough, it's '#' else ' ' (natural)
        (f-d)*100);  // number of cents; stdio rounds it to integer
}

2
भयानक scanfप्रारूप स्ट्रिंग के लिए +1 । मुझे नहीं पता था कि आप ऐसा कर सकते हैं। मैं आपको बाद में आउटपुट कोड की जांच करूंगा (मैंने सोचा कि सी में ऐसा करने के बारे में और हालांकि आउटपुट के लिए मेरे साथ भी ऐसा ही कुछ हुआ है, मैं पूरी तरह से प्रतिस्पर्धात्मक तरीके से करने का एक तरीका नहीं देख सका।) मुझे लगता d+9है क्योंकि आप अनुक्रमित हैं। नोट ए इसलिए आपको नोट पर C पर सूचकांक में ऑक्टेव संख्या को समायोजित करना होगा: मुझे आश्चर्य है कि अगर उसके आसपास कोई रास्ता है।
लेवल रिवर सेंट

हां, +9 इस तथ्य के लिए क्षतिपूर्ति करता है कि ओक्टेव्स सी पर शुरू होता है। यह या तो है या नोट नाम की गणना के लिए एक समान निर्धारण कर रहा है। नोट नामों के लिए, परिपत्र बदलाव एक LUT द्वारा लागू किया जा सकता है, लेकिन मुझे उनकी गणना करने का अधिक "गणितीय" तरीका पसंद है।
अनातोली

1

जावास्क्रिप्ट (199)

जैसे कहो t('[X-]',314.1592)

t=(s,f)=>{l=s.length-1;p='C C# D D# E F F# G G# A B H'.split(' ');n=12*Math.log2(f*l/(l-s.indexOf('X'))/16.3515978);m=n+.5|0;return p[m%12]+(n/12|0)+' '+((n-m)*100+.5|0)}

फिक्स्ड। (जब से मैं यूरोप में रहता हूं मैंने B = की बजाय B और H का उपयोग किया है)


फ़्लावर, क्या आप जर्मन हैं? मैंने हमेशा जर्मन संकेतन के रूप में बी और एच के बारे में सोचा, न कि यूरोपीय संकेतन के रूप में। यूके और आयरलैंड Bb और B का उपयोग करते हैं। स्पेन और इटली SIb और SI का उपयोग करते हैं (जैसा कि DO RE MI FA SOL LA SI)। वैसे भी यह केवल एक चरित्र की बचत है।
लेवल रिवर सेंट

हां, मैं एक जर्मन भाषी देश हूं, मुझे इस बात की जानकारी नहीं थी कि अन्य यूरोपीय देश उस डोरमी प्रणाली का उपयोग करते हैं (मैंने केवल लोगों को सुना है कि वे बच्चों की शिक्षा में इसका उपयोग करते हैं)। वैसे भी यह मुख्य रूप से एक मजाक था क्योंकि आपने कहा था कि यह केवल 1
चार्ट

यह गलत तरीके से सेंट की संख्या को गोल करने के लिए लगता है यदि सेंट की संख्या नकारात्मक है (उदाहरण के लिए, t('[---X--]',11.7103)(अंतिम उदाहरण) -10इसके बजाय-11
es1024

का उपयोग करना p="C0C#0D0D#0E0F0F#0G0G#0A0B0H".split(0)आपको अतिरिक्त 2 वर्ण बचाता है।
सीन लाथम

@ es1024 ओह मुझे पता होना चाहिए: ऐसा इसलिए है क्योंकि मैंने गोल फ़ंक्शन को लागू किया है round(x) = x+.5|0जिसके द्वारा केवल सकारात्मक संख्याओं के लिए सही है, मैं बाद में इसे ठीक कर दूंगा। @ipi धन्यवाद!
त्रुटी

1

पायथन 3: 175

import math
def t(b,s):l=len(s)-1;n=12*math.log2(b*l/(l-s.index("X"))/16.35);m=round(n);return"%s%s%+d"%(("C C# D D# E F F# G G# A A# B".split()*99)[m],m//12,round(100*(n-m)))

Ungolfed:

import math

c0 = 16.35

def tuning (base_frequency, string):
    return formatted (note_number (frequency (base_frequency, string)))

def formatted (note_number):
    return "{name}{octave:d}{cents:+d}".format (name=note_name (note_number),
                             octave=octave (note_number),
                             cents=cents_out (note_number))

def note_name (note_number):
    return ("C C# D D# E F F# G G# A A# B".split() * 99)[round (note_number)]

def note_number (frequency):
    return 12 * math.log2 (frequency / c0)

def octave (note_number):
    return round (note_number) // 12

def cents_out (note_number):
    return round (100 * (note_number - round (note_number)))

def frequency (base_frequency, string):
    string_length = len (string) - 1
    held_length = string_length - string.index ("X")
    return base_frequency * string_length / held_length

if "__main__" == __name__:

    print ("Testing functions against known values...")
    assert "A4+0"     == tuning (220,      "[-----X-----]")
    assert "A5+0"     == tuning (220,      "[--------X--]")
    assert "D5-2"     == tuning (440,      "[--X--------]")
    assert "B4-49"    == tuning (440,      "[X----------]")
    assert "A#4+19"   == tuning (314.1592, "[X-]")
    assert "D#9+8"    == tuning (400,      "[-----------------------X]")
    assert "D#11+8"   == tuning (100,      "[--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------X]")
    assert "D#1+49"   == tuning (10,       "[--X]")
    assert "A0-11"    == tuning (11.7103,  "[---X--]")
    print ("Tests passed.")
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.