diff --git a/LEARN.md b/LEARN.md new file mode 100644 index 0000000..dda0f9f --- /dev/null +++ b/LEARN.md @@ -0,0 +1,3 @@ +## Ruby Rocks + +You can visit any folder in this repository for learning. Like the `ruby-hacktoberfest-2022` folder contains a plenty of basic programs which are added in Ruby language during the `hacktoberfest-2022`. Also you can visit `ruby-hacktoberfest-2023` folder for learning ruby programs contributed during `hacktoberfest-2023`. diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..6dfc511 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Shehroz Irfan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/contributing.md b/contributing.md index af10ef3..03fb4b4 100644 --- a/contributing.md +++ b/contributing.md @@ -1,7 +1,12 @@ # Ruby Rocks # How to contribute -1. You can contribute in terms of Code +1. You can contribute in terms of Code: - Write program/code which solves any problem using Ruby. +2. You can contribute in terms of documentation: + - By adding the documentation for any `Ruby concept` + +Note: Add your contributions to `ruby-hacktoberfest-2023` folder. + ## Following the procedure you can make your contribution with ease. ### Step 0 Star and Fork this repository diff --git a/readme.md b/readme.md index 47e0193..a57bb08 100644 --- a/readme.md +++ b/readme.md @@ -1,15 +1,33 @@ -# Important -### Kindly View Contributing.md file to see the guidelines for hacktoberfest 2022 before contributing to this repository. +# Ruby Rocks +- This is the repository for beginners so that they can use this repository to make their first contribution to an open source project on GitHub. You can solve any programming problem using Ruby and add to this repository. +- This repository was also part of Hacktoberfest-2022 -# Welcome to Ruby-Rocks Repository -## It is specially for Hacktoberfest 2022 +## How to contribute +Visit [CONTRIBUTING.md](https://github.com/ShehrozIrfan/ruby-rocks/blob/first-ruby-code/contributing.md) for contribution to this project. -Hacktoberfest2022 Banner +## How to Learn +Visit [LEARN.md](https://github.com/ShehrozIrfan/ruby-rocks/blob/first-ruby-code/LEARN.md) for learning. -## What is Hacktoberfest? -Hacktoberfest is a month-long celebration of open source software run by DigitalOcean in partnership with GitHub and Twilio. Hacktoberfest is open to everyone in our global community! Four quality pull requests must be submitted to public GitHub repositories. You can sign up anytime between October 1 and October 31. +## Hacktoberfest 2023 +Hacktoberfest2022 Banner -## Contributors ✨ +

+ This year marks the 10th anniversary of Hacktoberfest, and we’re calling on your support! Whether it’s your first time participating—or your tenth—it’s almost time to hack out four pristine pull/merge requests as we continue our month of support for open source. +

+ +#### What is Hacktoberfest? +

+ Hacktoberfest is a month-long celebration of open source software run by DigitalOcean in partnership with GitHub and Twilio. Hacktoberfest is open to everyone in our global community! Four quality pull requests must be submitted to public GitHub repositories. You can [sign up](https://hacktoberfest.com/) anytime between October 1 and October 31. +

+ +## Hacktoberfest 2022 +This repository was also part of hacktoberfest 2022. + +Hacktoberfest2022 Banner + +--- + +## Our Contributors diff --git a/ruby-hacktoberfest-2022/file_create_edit_close.rb b/ruby-hacktoberfest-2022/file_create_edit_close.rb new file mode 100644 index 0000000..6712f42 --- /dev/null +++ b/ruby-hacktoberfest-2022/file_create_edit_close.rb @@ -0,0 +1,24 @@ +# This is a file handling (create, writing, and closing) program using Ruby + +def fileHandling + puts 'Please write the name of the file you want to create. Make sure and add the filetype at the end (e.g. .txt, .rb): ' + name = gets.chomp.to_s + puts 'Please write what you are wanting to put into the file: ' + toWrite = gets.chomp.to_s + # First we will create a file which is assigned to a variable. + # This file will be created and added to the current project directory that this program is in + # The name of the file will be what was entered at the first prompt. + fileObject = File.new(name, 'w+') + + # Next we are going to write to the file + # The content of the file will be what was input at the second prompt. + fileObject.syswrite(toWrite) + + # Finally we will close the file that we created and wrote to + puts "The file you made and wrote to is located in the current directory! It's name is #{name}!" + fileObject.close + + # Now go and find the file you created, and see how you were able to to create, edit, and close a file with Ruby! +end + +fileHandling diff --git a/ruby-hacktoberfest-2023/BreakerCode.rb b/ruby-hacktoberfest-2023/BreakerCode.rb new file mode 100755 index 0000000..e8492b7 --- /dev/null +++ b/ruby-hacktoberfest-2023/BreakerCode.rb @@ -0,0 +1,73 @@ +class CodeBreaker + attr_accessor :code, :puzzle_type + + def initialize(puzzle_type) + @puzzle_type = puzzle_type + @code = generate_code + end + + def generate_code + Array.new(4) { rand(0..9) } + end + + def check_guess(guess) + feedback = Feedback.new + + case @puzzle_type + when :addition + feedback.correct_digits = guess.sum == @code.sum + when :subtraction + feedback.correct_digits = guess.first - guess.last == @code.first - @code.last + when :multiplication + feedback.correct_digits = guess.inject(:*) == @code.inject(:*) + when :division + feedback.correct_digits = guess.first / guess.last == @code.first / @code.last + when :prime_number + feedback.correct_digits = guess.all? { |digit| digit.prime? } && @code.all? { |digit| digit.prime? } + when :fibonacci + feedback.correct_digits = guess.last == @code.last + @code.last - 1 + else + raise "Invalid puzzle type" + end + + feedback.correct_positions = guess.each_with_index.count { |digit, index| digit == @code[index] } + + feedback + end + + def game_over? + feedback = check_guess(@code) + + feedback.correct_digits == 4 && feedback.correct_positions == 4 + end +end + +class Feedback + attr_accessor :correct_digits, :correct_positions + + def initialize + @correct_digits = 0 + @correct_positions = 0 + end +end + +def main + puts "Choose a puzzle type (addition, subtraction, multiplication, division, prime_number, fibonacci):" + puzzle_type = gets.chomp.to_sym + + code_breaker = CodeBreaker.new(puzzle_type) + + until code_breaker.game_over? + puts "Enter your guess (4 digits):" + guess = gets.chomp.split("").map(&:to_i) + + feedback = code_breaker.check_guess(guess) + + puts "Correct digits: #{feedback.correct_digits}" + puts "Correct positions: #{feedback.correct_positions}" + end + + puts "Congratulations! You broke the code." +end + +main diff --git a/ruby-hacktoberfest-2023/Enigma.rb b/ruby-hacktoberfest-2023/Enigma.rb new file mode 100644 index 0000000..9074731 --- /dev/null +++ b/ruby-hacktoberfest-2023/Enigma.rb @@ -0,0 +1,105 @@ +class Rotor + attr_accessor :notches + + def initialize(notches) + @notches = notches + end + + def notch + @notches.sample + end +end + +class CodeBreakerEnigma + attr_accessor :code, :rotors, :reflector + + def initialize(rotors, reflector) + @rotors = rotors + @reflector = reflector + @code = generate_code + end + + def generate_code + Array.new(3) { @rotors.sample.notch } + end + + def encrypt(letter) + letter = @rotors[0].encrypt(letter) + letter = @rotors[1].encrypt(letter) + letter = @rotors[2].encrypt(letter) + letter = @reflector.encrypt(letter) + letter = @rotors[2].decrypt(letter) + letter = @rotors[1].decrypt(letter) + letter = @rotors[0].decrypt(letter) + letter + end + + def decrypt(letter) + letter = @rotors[0].decrypt(letter) + letter = @rotors[1].decrypt(letter) + letter = @rotors[2].decrypt(letter) + letter = @reflector.decrypt(letter) + letter = @rotors[2].encrypt(letter) + letter = @rotors[1].encrypt(letter) + letter = @rotors[0].encrypt(letter) + letter + end + + def game_over? + @code == @rotors.map(&:notch) + end + + def check_guess(guess) + feedback = Feedback.new + + guess.each_with_index do |letter, index| + if letter == @code[index] + feedback.correct_letters += 1 + feedback.correct_positions += 1 + end + end + + feedback + end + + def get_rotors + @rotors + end + + def get_reflector + @reflector + end +end + +class Feedback + attr_accessor :correct_letters, :correct_positions + + def initialize + @correct_letters = 0 + @correct_positions = 0 + end +end + +def main + rotors = [Rotor.new([1, 2, 3]), Rotor.new([4, 5, 6]), Rotor.new([7, 8, 9])] + reflector = "D" + + code_breaker_enigma = CodeBreakerEnigma.new(rotors, reflector) + + until code_breaker_enigma.game_over? + puts "Enter your guess (3 letters):" + guess = gets.chomp.split("").map(&:upcase) + + feedback = code_breaker_enigma.check_guess(guess) + + puts "Correct letters: #{feedback.correct_letters}" + puts "Correct positions: #{feedback.correct_positions}" + end + + if code_breaker_enigma.game_over? + puts "Congratulations! You broke the code." + else + puts "Sorry, you ran out of guesses." + end +end +main diff --git a/ruby-hacktoberfest-2023/Evaluating_PIN.rb b/ruby-hacktoberfest-2023/Evaluating_PIN.rb new file mode 100644 index 0000000..2a708d8 --- /dev/null +++ b/ruby-hacktoberfest-2023/Evaluating_PIN.rb @@ -0,0 +1,181 @@ + +$numGuesses = 0 +$wasGuessed = false +$placeFound = nil + +def guess(pin) #Guesses PINs in common patterns. +#Pattern Guesses + #Most common + check(pin, "1234", :MOST_COMMON) + + if $wasGuessed;return;end + check(pin, "4321", :MOST_COMMON) + + if $wasGuessed;return;end + check(pin, "9876", :MOST_COMMON) + + #Center of PIN pad + if $wasGuessed;return;end + check(pin, "2580", :KEYPAD) + + #Center of keyboard numpad + if $wasGuessed;return;end + check(pin, "8520", :KEYPAD) + + #All same num (Ex: 3333) + if $wasGuessed;return;end + for i in 0..9 + guess = i.to_s*4 + $numGuesses += 1 + + if check(pin, guess, :ALL_SAME) + return + end + end + + #Many similar numbers (Ex: 7737) + if $wasGuessed;return;end + for digit in 0..3 #Cycles through which digit to change + for i in 0..9 + for j in 0..9 + guess = j.to_s*4 + guess[digit] = i.to_s #Changes 1 digit + if check(pin, guess, :MANY_SAME) + return + end + end + end + end + + #Couplets (Ex: 2424) + if $wasGuessed;return;end + for i in 0..9 + for j in 0..9 + guess = (i.to_s + j.to_s)*2 + + if check(pin, guess, :COUPLETS) + return + end + end + end + + #Palindromes (Ex: 9559) + if $wasGuessed;return;end + for i in 0..9 + for j in 0..9 + guess = (i.to_s + j.to_s) + guess += guess.reverse + + if check(pin, guess, :PALINDROME) + return + end + end + end + +#Date Guesses + #MM/YY + guessDate(1, 12, 1, 99, pin) + + #DD/MM + if $wasGuessed;return;end + guessDate(1, 31, 1, 12, pin) + + #MM/DD + if $wasGuessed;return;end + guessDate(1, 12, 1, 31, pin) + + #YYYY + if $wasGuessed;return;end + guessDate(19, 20, 0, 99, pin) + +#Bruteforce + if $wasGuessed;return;end + bruteforce(pin) +end + +def guessDate(min1, max1, min2, max2, pin) #Guesses PINs in date formats + for i in min1..max1 + for j in min2..max2 + if i < 10 + half1 = twoDigitNum(i) + else + half1 = i.to_s + end + + if j < 10 + half2 = twoDigitNum(j) + else + half2 = j.to_s + end + + guess = half1 + half2 + + if check(pin, guess, :DATES) + return + end + end + end +end + +def bruteforce(pin) + for i in 0..9 + for j in 0..9 + for k in 0..9 + for l in 0..9 + guess = i.to_s + j.to_s + k.to_s + l.to_s + + if check(pin, guess, :BRUTEFORCE) + return + end + end + end + end + end +end + +def showResults(pin) + puts "\nTook #{$numGuesses} tries to find #{pin}." + + case $placeFound + when :MOST_COMMON, :ALL_SAME + puts "Really. I hope you don't actually use this as your real PIN." + when :KEYPAD + puts "Anyone could guess that immediately! Those are the center numbers of a keypad!" + when :MANY_SAME, :COUPLETS, :PALINDROME + puts "Any good guessing algorithm finds simple-to-remember patterns first! A person might be able to guess this, too, if they're patient." + when :DATES + puts "An algorithm might guess dates, because they're memorable (although you might not have intended your PIN to be one). And a person can figure out what dates are important to you and guess it, too (if you *did* intent it to be one)." + when :BRUTEFORCE + puts "Your PIN is harder for an algorithm or person to guess. Good choice!" + end +end + +def check(pin, guess, loc) + $numGuesses += 1 + + if pin.to_s == guess.to_s + $wasGuessed = true + $placeFound = loc + return true + else + return false + end +end + +def twoDigitNum(inNum) #Returns 2-digit number as string + return "0" + inNum.to_s +end + +puts "Enter a 4-digit PIN:\t" +pin = gets.chomp + +while pin.length != 4 + if pin.length != 4 + puts "Must be 4 digits! Try again:\t" + end + + pin = gets.chomp +end + +guess(pin) +showResults(pin) diff --git a/ruby-hacktoberfest-2023/Factorial.rb b/ruby-hacktoberfest-2023/Factorial.rb new file mode 100644 index 0000000..76848ff --- /dev/null +++ b/ruby-hacktoberfest-2023/Factorial.rb @@ -0,0 +1,13 @@ +def factorial(n) + return 1 if n == 0 + n * factorial(n - 1) +end + +puts "Enter a positive integer:" +number = gets.chomp.to_i + +if number < 0 + puts "Please enter a non-negative number." +else + puts "Factorial of #{number} is: #{factorial(number)}" +end diff --git a/ruby-hacktoberfest-2023/Fibonacci.rb b/ruby-hacktoberfest-2023/Fibonacci.rb new file mode 100644 index 0000000..ac56da0 --- /dev/null +++ b/ruby-hacktoberfest-2023/Fibonacci.rb @@ -0,0 +1,25 @@ +=begin +Ruby program to print Fibonacci series +without recursion +=end + +first=0 +second=1 +nextterm=0 + +puts "Enter the number of terms:-" +n=gets.chomp.to_i + +puts "The first #{n} terms of Fibonacci series are:-" +c=1 +while(c<=n+1) + if(c<=1) + nextterm=c + else + puts nextterm + nextterm=first+second + first=second + second=nextterm + end + c+=1 +end diff --git a/ruby-hacktoberfest-2023/MathicalRealm.rb b/ruby-hacktoberfest-2023/MathicalRealm.rb new file mode 100644 index 0000000..5856deb --- /dev/null +++ b/ruby-hacktoberfest-2023/MathicalRealm.rb @@ -0,0 +1,127 @@ +class Player + attr_accessor :player_number, :lives, :score + + def initialize(player_number, lives = 3) + @player_number = player_number + @lives = lives + @score = 0 + end + + def decrease_life + @lives -= 1 + end + + def correct_answer + @score += 1 + end + + def lost_all_lives + @lives == 0 + end + + def to_s + "Player #{@player_number} with #{@lives} lives and #{@score} points." + end + end + + class Game + attr_accessor :player1, :player2, :current_player, :difficulty, :question_type, :time_limit + + def initialize(difficulty: :easy, question_type: :addition, time_limit: 10) + @player1 = Player.new(1) + @player2 = Player.new(2) + @current_player = @player1 + @difficulty = difficulty + @question_type = question_type + @time_limit = time_limit + end + + def game_over? + @player1.lost_all_lives || @player2.lost_all_lives + end + + def switch_player + @current_player = @current_player == @player1 ? @player2 : @player1 + end + + def game_loop + until game_over? + question = Question.new(difficulty: @difficulty, question_type: @question_type) + puts question.to_s + + start_time = Time.now + + answer = gets.chomp.to_i + + end_time = Time.now + + time_elapsed = end_time - start_time + + if question.correct_answer?(answer) && time_elapsed <= @time_limit + @current_player.correct_answer + puts "Correct! Your score is now #{@current_player.score}." + else + @current_player.decrease_life + puts "Incorrect. You have #{@current_player.lives} lives remaining." + end + + switch_player + end + + puts "Game over! The winner is #{@current_player} with #{@current_player.score} points." + end + end + + class Question + attr_accessor :number1, :number2, :answer, :difficulty, :question_type + + def initialize(difficulty: :easy, question_type: :addition) + @difficulty = difficulty + @question_type = question_type + + case @difficulty + when :easy + @number1 = rand(10) + @number2 = rand(10) + when :medium + @number1 = rand(100) + @number2 = rand(100) + when :hard + @number1 = rand(1000) + @number2 = rand(1000) + end + + case @question_type + when :addition + @answer = @number1 + @number2 + when :subtraction + @answer = @number1 - @number2 + when :multiplication + @answer = @number1 * @number2 + when :division + @answer = @number1 / @number2 + end + end + + def to_s + case @question_type + when :addition + "#{@number1} + #{@number2} = ?" + when :subtraction + "#{@number1} - #{@number2} = ?" + when :multiplication + "#{@number1} * #{@number2} = ?" + when :division + "#{@number1} / #{@number2} = ?" + end + end + + def correct_answer?(answer) + answer == @answer + end + end + + # Start the game + game = Game.new(difficulty: :medium, question_type: :multiplication, time_limit: 15) + game.game_loop + diff --git a/ruby-hacktoberfest-2023/factorial_iterative.rb b/ruby-hacktoberfest-2023/factorial_iterative.rb new file mode 100644 index 0000000..bedcf18 --- /dev/null +++ b/ruby-hacktoberfest-2023/factorial_iterative.rb @@ -0,0 +1,24 @@ +def factorial_iterative(n) + if n < 0 + return "Factorial is not defined for negative numbers." + elsif n == 0 + return 1 + else + result = 1 + while n > 0 + result *= n + n -= 1 + end + return result + end +end + +# Get user input +print "Enter a non-negative integer to calculate its factorial: " +num = gets.chomp.to_i + +if num < 0 + puts "Factorial is not defined for negative numbers." +else + puts "Iterative Factorial of #{num} is #{factorial_iterative(num)}" +end diff --git a/ruby-hacktoberfest-2023/hello.rb b/ruby-hacktoberfest-2023/hello.rb new file mode 100644 index 0000000..42c1358 --- /dev/null +++ b/ruby-hacktoberfest-2023/hello.rb @@ -0,0 +1 @@ +puts "Welcome to Hacktoberfest 2023!" diff --git a/ruby-hacktoberfest-2023/multiply.rb b/ruby-hacktoberfest-2023/multiply.rb new file mode 100644 index 0000000..30163cf --- /dev/null +++ b/ruby-hacktoberfest-2023/multiply.rb @@ -0,0 +1,10 @@ +def multiply_numbers(a, b) + result = a * b + return result +end + +# Example usage: +num1 = 5 +num2 = 7 +product = multiply_numbers(num1, num2) +puts "The product of #{num1} and #{num2} is #{product}" diff --git a/ruby-hacktoberfest-2023/ninj.rb b/ruby-hacktoberfest-2023/ninj.rb new file mode 100755 index 0000000..f515a2a --- /dev/null +++ b/ruby-hacktoberfest-2023/ninj.rb @@ -0,0 +1,104 @@ +class NumberPuzzleMaster + attr_reader :secret_number, :best_score, :timer + + def initialize + @secret_number = Random.rand(100) + 1 + @best_score = nil + @timer = nil + end + + def set_difficulty(min, max) + @secret_number = Random.rand(min..max) + end + + def start_timer(seconds) + @timer = Timer.new(seconds) + @timer.start + end + + def play + puts "Welcome to the Number Puzzle Master!" + + # Get the player's desired difficulty level + puts "Choose a difficulty level:" + puts "1. Easy (1-10)" + puts "2. Medium (1-50)" + puts "3. Hard (1-100)" + + difficulty = gets.chomp.to_i + case difficulty + when 1 + set_difficulty(1, 10) + when 2 + set_difficulty(1, 50) + when 3 + set_difficulty(1, 100) + else + puts "Invalid difficulty level." + exit + end + + # Start the timer + start_timer(10) + + # Start the game loop + loop do + # Check if the timer has expired + if @timer && @timer.expired? + puts "Time's up!" + break + end + + # Get the player's guess + puts "Guess a number from 1 to #{@secret_number}:" + guess = gets.chomp.to_i + + # Check if the player guessed correctly + if guess == @secret_number + puts "Congratulations! You guessed correctly!" + break + else + puts "Incorrect guess." + end + end + + # Display the player's score + score = @timer ? @timer.remaining_time : 0 + puts "Your score is: #{score}" + + # Update the player's best score + if @best_score.nil? || score > @best_score + @best_score = score + end + + # Display the player's best score + puts "Your best score is: #{@best_score}" + end +end + +class Timer + attr_reader :start_time, :end_time + + def initialize(seconds) + @start_time = Time.now + @end_time = Time.now + seconds + end + + def start + @start_time = Time.now + end + + def expired? + Time.now >= @end_time + end + + def remaining_time + @end_time - Time.now + end +end + +# Create a new game +game = NumberPuzzleMaster.new + +# Start the game +game.play diff --git a/ruby-hacktoberfest-2023/trivia.rb b/ruby-hacktoberfest-2023/trivia.rb new file mode 100644 index 0000000..0d3f1b9 --- /dev/null +++ b/ruby-hacktoberfest-2023/trivia.rb @@ -0,0 +1,41 @@ +class Question + attr_reader :question, :answer + + def initialize(question, answer) + @question = question + @answer = answer + end +end + +class Game + def initialize + @questions = [ + Question.new("What is the capital of France?", "Paris"), + Question.new("Who wrote 'To Kill a Mockingbird'?", "Harper Lee"), + Question.new("What is the chemical symbol for Hydrogen?", "H") + ] + @score = 0 + end + + def start + puts "Welcome to Trivia Game!" + + @questions.each do |question| + puts question.question + print "Your answer: " + user_answer = gets.chomp + + if user_answer.downcase == question.answer.downcase + puts "Correct!" + @score += 1 + else + puts "Sorry, that's incorrect. The correct answer is #{question.answer}." + end + end + + puts "Game over! Your score was #{@score}." + end +end + +game = Game.new +game.start