Prev: Random integer within a range?
Next: Please help!
From: Ben Rho on 2 Mar 2010 20:53 Daniel X Moore wrote: > Steve wants to be a legendary guitarist. Is it OK if I use piano chords instead of guitar chords (I think the answer is yes, but I wanted to make sure)? I used to be a pianist and I think it would be easier to do piano chords (there isn't much different, but my dad - a hobby guitarist - and I don't understand each other when talking about chords). This is the first Ruby Quiz I've worked on (actually, it's one of my first Ruby programs all together, because Ruby Quiz is what introduced me to Ruby!). I've got a solution in the workings (easy to add new chords, too), but unfortunately homework takes precedence so I won't/can't finish or post it yet :/ From what it says on the 1st Ruby Quiz website (and the 2nd), it seems like everything related is allowed. James Edward Gray II wrote: (on http://rubyquiz.com/) > Again, you can submit anything you like. There's no right or wrong answer to Ruby Quiz. The goals are to think, learn, and have a good time. You have to decide what does that for you. However, it also says that if the quizmaster includes a criteria in the quiz, then thats what it's graded by. Is "guitar chords" a criteria? Oops, misspelled chords throughout, I think I caught them all but if you'd mentally s/cord/chord/g that'd be great :P -- Posted via http://www.ruby-forum.com/.
From: Daniel Moore on 2 Mar 2010 23:53 Wow, this is some great discussion! Both piano and guitar chords are fine, some of the benefits on these broader quizzes are seeing alternative solutions and understanding the problem from different angles. Likewise the discussions about the differences between classical and jazz are also welcome. After all, the most important part of any programming project is understanding the domain. This writeup is going to be a fun one. Keep the solutions and the discussion coming! -- -Daniel http://rubyquiz.strd6.com
From: Brian Candler on 3 Mar 2010 04:42 David Springer wrote: > OK > > Here is my solution. $ ruby Chords_DNS.rb C7 Chord "C7", C, E, G, A# That should be a Bb, not an A#. C7b5 Chord "C7b5", C, E, F#, A# That's my favourite chord, the Lydian Dominant, but I would have called it C7#4 as the scale also contains a perfect 5th. It's odd as it includes both sharps and flats (F# and Bb). The Simpsons theme tune is an example of a melody using this scale. Regards, Brian. -- Posted via http://www.ruby-forum.com/.
From: Ben Rho on 3 Mar 2010 09:50 Daniel X Moore wrote: > Wow, this is some great discussion! Both piano and guitar chords are > fine, some of the benefits on these broader quizzes are seeing > alternative solutions and understanding the problem from different > angles. Likewise the discussions about the differences between > classical and jazz are also welcome. After all, the most important > part of any programming project is understanding the domain. > > This writeup is going to be a fun one. Keep the solutions and the > discussion coming! Thanks for the confirmation. I agree, can't wait until the writeup is posted. On reviewing David Springer's solution, I found that our solutions are quite similar (actually, mine's pretty much the same except shorter and with more regex - after completion, it'll probably be a lot closer). Would both of our solution merit entries on the Ruby Quiz website? Also, could someone with some time give a brief run-through of what happens when Evan Hanson's code is run? I don't think I understand it. What I think happens: Make a new Chord object Chord#initialize: Set @name to the note and @numval to to the notes position in Map.sharps Parse note skipping the first character and sharp/flat it if it's b or # (I'd use a different method though, becouse susb or something would be picked up) Flat things by subtracting one from @numval (I think it should have an error check, @numval=11 if (@numval-=1)<0 to make it easier to port to other languages) and changing the value of @name (easier done in my opinion by using Map.flats[@numval]) Sharp things by adding one from @numval (I think it should have an error check, @numval=0 if (@numval+=1)==12 to make it easier to port to other languages) and changing the value of @name (easier done in my opinion by using Map.sharps[@numval]) Chord#to_s: Returns @name But that would only return the input in a fancy way! I don't see how it returns chords. David Springer wrote: > I'm not sure about the etiquette of attaching a non-compressed file. Personally, I prefer the attachment of non-compressed files to the attachment of compressed files or inline code, because it keeps the thread short, makes the code easier to read (all-the-way-left-justified and full width), and the code is easier to download (for me, it takes just 10 keystrokes, no need to search for where it begins/ends and click+drag). That's just me, though, and Hal Fulton doesn't agree: > Frankly, I'd rather see inline code rather than an attachment. Especially if attaching doesn't save any space. Thanks in advance, Ben. -- Posted via http://www.ruby-forum.com/.
From: Brian Candler on 3 Mar 2010 11:34
Here's my version. I think it handles the "spelling" of 7-note scales correctly, but the 8-note scales don't always give a satisfactory answer, e.g. C#dim7 => C# E Fx A# (most people would use G rather than F double sharp) Regards, Brian. class Note NOTES = "ABCDEFG" SEMITONES = [0, 2, 3, 5, 7, 8, 10] # semitones above A attr_reader :note # 0-6 representing A-G attr_reader :semi # 0-11 representing A to G#/Ab ACCIDENTAL = {"bb"=>-2, "b"=>-1, ""=>0, "#"=>1, "x"=>2} # Parse a note like "C#..." # Return a Note object plus the remainder of the string def self.parse(str) raise "Invalid note" unless str =~ /\A([A-G])([b#]?)(.*)\z/ note = NOTES.index($1) semi = SEMITONES[note] + ACCIDENTAL[$2] return [new(note, semi), $3] end # Create a note. # new(0,0) => A # new(0,1) => A# # new(1,1) => Bb # new(1,2) => B # new(1,3) => B# # new(2,2) => Cb # new(2,3) => C def initialize(note, semi=SEMITONES[note]) @note, @semi = note % 7, semi % 12 end def to_s acc = (@semi - SEMITONES[@note] + 6) % 12 - 6 str = if acc < 0 "b" * -acc elsif acc == 2 "x" else "#" * acc end NOTES[@note,1] + str end # return a new note which is N degrees along and M semitones along. e.g. # fsharp(1,1) => G (one note up, one semitone up) # fsharp(1,2) => G# (one note up, two semitones up) # fsharp(2,2) => Ab (two notes up, two semitones up) def offset(degree_offset, semi_offset) self.class.new(@note + degree_offset, @semi + semi_offset) end # return an array of notes, given an array of [degree,semitone] offsets # representing a scale, and an array of indexes into that array def scale(pairs, degrees = [1,3,5,7]) res = [] degrees.each_with_index do |d,i| pair = pairs[(d-1) % pairs.size] res << offset(pair[0], pair[1]) end res end # Convert a scale into its nth mode def self.mode(pairs, mode) a = pairs.dup (mode-1).times { a.push(a.shift) } d0, s0 = a.first a.map { |d,s| [d-d0, s-s0] } end Ionian = [[0,0], [1,2], [2,4], [3,5], [4,7], [5,9], [6,11]] Dorian = mode(Ionian, 2) Phrygian = mode(Ionian, 3) Lydian = mode(Ionian, 4) Mixolydian = mode(Ionian, 5) Aeolian = mode(Ionian, 6) Locrian = mode(Ionian, 7) MelodicMinor = [[0,0], [1,2], [2,3], [3,5], [4,7], [5,9], [6,11]] PhrygianNatural6 = mode(MelodicMinor, 2) LydianAugmented = mode(MelodicMinor, 3) LydianDominant = mode(MelodicMinor, 4) MixolydianFlat6 = mode(MelodicMinor, 5) AeolianFlat5 = mode(MelodicMinor, 6) Altered = mode(MelodicMinor, 7) Diminished = [[0,0], [1,2], [2,3], [3,5], [3,6], [4,8], [5,9], [6,11]] EightNoteDominant = mode(Diminished, 2) Chords = { "" => [Ionian], "m" => [MelodicMinor], "m7" => [Dorian], "7" => [Mixolydian], "7+4" => [LydianDominant, [1,3,4,5,7]], "7alt" => [Altered, [1,3,5,7,9,11,13]], "dim7" => [Diminished, [1,3,5,7]], "7b9" => [EightNoteDominant, [1,3,5,7,2,4,6,8]], # Expand this at your leisure } def self.chord(str) root, chordsym = parse(str) chordarg = Chords[chordsym] || (raise "Unknown chord: #{chordsym.inspect}") root.scale(*chordarg) end end if __FILE__ == $0 while str = $stdin.gets str.chomp! puts Note.chord(str).join(" ") end end -- Posted via http://www.ruby-forum.com/. |