Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I am looking to update a construct on screen as the input changes. The construct will look like so:
puts " | | "
puts " | | "
puts "----+----+----"
puts "make an input (1/2/3/4/5/6)"
selection = gets.chomp
#process selection, returns value, value to be updated in construct.
I defined the spaces for the values as a 2x3 array. The value returned, for example, can be '2' to be stored in space [0][1] (row 1, col 2). The output should then look like:
| 2 |
| |
----+----+----
This needs to happen without re-printing the construct. When the user is prompted (in a loop) to make another selection, again the construct should be updated without re-printing.
May I interest you, fine gentleman, in the battle between good and evil? Heavily inspired by TTT:
require 'dispel'
class Lucky6
BOARD = <<-BOARD.gsub /^\s+/, ''
| X | X | X |
| X | X | X |
----+---+----
BOARD
attr_reader :position
def initialize
#fields = Array.new(6) { ' ' }
#position = 0
end
def board
index = -1
BOARD.gsub(" X ") do
index += 1
field = #fields[index]
#position == index ? "[#{field}]" : " #{field} "
end
end
def set(position)
#position = position.pred
#fields[#position] = position
end
end
def draw(l6)
[l6.board, "1..6=Set r=Reset q=Quit"].join("\n")
end
Dispel::Screen.open do |screen|
l6 = Lucky6.new
screen.draw draw(l6)
Dispel::Keyboard.output do |key|
case key
when ('1'..'6') then l6.set(key.to_i)
when "r" then l6 = Lucky6.new
when "q" then break
end
screen.draw draw(l6)
end
end
What you are asking is not possible using technique of \r, but you can use a trick of clearing the screen as shown below
matrix = [ ["", "", ""], ["", "", ""]]
pos_to_index = [[0, 0], [0, 1], [0, 2], [1,0], [1,1], [1,2]]
system("cls")
begin
print "make an input (1/2/3/4/5/6)\n"
selection = gets.chomp
system("cls")
if (selection.to_i <= pos_to_index.size)
pos = pos_to_index[selection.to_i - 1]
matrix[pos[0]][pos[1]] = selection
matrix.each { |a| a.each { |i| print " #{i.empty? ? ' ' : i} |" }; puts }
puts "---+---+----"
end
end while (not selection.empty?)
PS: system("cls") works on windows, if it does not work for you, try system("clear") as explained here
Related
I'm writing a program which takes input, stores it as a hash and sorts the values.
I'm having trouble comparing a current hash value with a variable.
Sample Input:
3
A 1
B 3
C 5
A 2
B 7
C 2
Sample Output:
A 1 2
B 3 7
C 2 5
Everything works apart from this part, and I'm unsure why.
if values.key?(:keys)
if values[keys] >= val
values.store(keys,val.prepend(val + " "))
else
values.store(keys,val.concat(" " + val))
end
else
values.store(keys,val)
end
i = i + 1
end
Rest of code:
#get amount of records
size = gets.chomp
puts size
size = size.to_i
values = Hash.new(0)
i = 0
while i < (size * 2)
text = gets.chomp
#split string and remove space
keys = text.split[0]
val = text.split[1]
#check if key already exists,
# if current value is greater than new value append new value to end
# else put at beginning of current value
if values.key?(:keys)
if values[keys] >= val
values.store(keys,val.prepend(val + " "))
else
values.store(keys,val.concat(" " + val))
end
else
values.store(keys,val)
end
i = i + 1
end
#sort hash by key
values = values.sort_by { |key, value| key}
#output hash values
values.each{|key, value|
puts "#{key}:#{value}"
}
Could anyone help me out? It would be most appreciated.
The short answer is that there are two mistakes in your code. Here is the fixed version:
if values.key?(keys)
if values[keys] >= val
values.store(keys,values[keys].prepend(val + " "))
else
values.store(keys,values[keys].concat(" " + val))
end
else
values.store(keys,val)
end
The if statement was always evaluating as false, because you were looking for hash key named :keys (which is a Symbol), not the variable you've declared named keys.
Even with that fixed, there was a second hidden bug: You were storing a incorrect new hash value. val.concat(" " + val) would give you results like A 2 2, not A 1 2, since it's using the new value twice, not the original value.
With that said, you code is still very confusing to read... Your variables are size, i, text, val, values, key and keys. It would have been a lot easier to understand with clearer variable names, if nothing else :)
Here is a slightly improved version, without changing the overall structure of your code:
puts "How may variables to loop through?"
result_length = gets.chomp.to_i
result = {}
puts "Enter #{result_length * 2} key-value pairs:"
(result_length * 2).times do
input = gets.chomp
input_key = input.split[0]
input_value = input.split[1]
#check if key already exists,
# if current value is greater than new value append new value to end
# else put at beginning of current value
if result.key?(input_key)
if result[input_key] >= input_value
result[input_key] = "#{input_value} #{result[input_key]}"
else
result[input_key] = "#{result[input_key]} #{input_value}"
end
else
result[input_key] = input_value
end
end
#sort hash by key
result.sort.to_h
#output hash result
result.each{|key, value|
puts "#{key}:#{value}"
}
h = Hash.new { |h,k| h[k] = [] }
input = ['A 1', 'B 3', 'C 5', 'A 2', 'B 7', 'C 2'].join("\n")
input.each_line { |x| h[$1] << $2 if x =~ /^(.*?)\s+(.*?)$/ }
h.keys.sort.each do |k|
puts ([k] + h[k].sort).join(' ')
end
# A 1 2
# B 3 7
# C 2 5
This would be a more Ruby-ish way to write your code :
input = "A 1
B 3
C 5
A 2
B 7
C 2"
input.scan(/[A-Z]+ \d+/)
.map{ |str| str.split(' ') }
.group_by{ |letter, _| letter }
.each do |letter, pairs|
print letter
print ' '
puts pairs.map{ |_, number| number }.sort.join(' ')
end
#=>
# A 1 2
# B 3 7
# C 2 5
I'm trying to create a tic-tac-toe game. I listed only the code for the relevant class and methods I got so far:
class Box
attr_reader :name, :row, :column
attr_accessor :is_marked, :contents
def initialize(name, row, column, is_marked=false, contents)
#name = name
#row = row
#column = column
#is_marked = is_marked
#contents = contents
end
def self.display_box
print '|#{contents}|'
end
end
#generate box instances
(1..9).each do |i|
if i > 3
col = i % 3
else
col = i
end
box#{i} = Box.new('box#{i}', (i/3).ceil, col, false, '_')
end
board = [[box1, box2, box3], [box4, box5, box6], [box7, box8, box9]]
def display_board
box1.display_box; box2.display_box; box3.display_box; print '\n'
box4.display_box; box5.display_box; box6.display_box; print '\n'
box7.display_box; box8.display_box; box9.display_box; print '\n'
end
display_board
I can't figure out why creating an instance of my class throws an error. The error is:
undefined local variable or method `box1' for <Context:0x000000024df8a8>
(repl):44:in display_board'
(repl):61:in initialize'
I tried running it with and without the 'self' in the display_box method, same error.
The problem is this line.
box#{i} = Box.new('box#{i}', (i/3).ceil, col, false, '_')
It seems like you're trying to create a bunch of variables named box1, box2, ... There might be away way to do that in ruby, but that's not it. You could do it with eval, but you don't want to this. As you can see from the rest of your code, working with a big pile of variables like that is annoying.
Instead, make an Array of boxes.
boxes[i] = Box.new("box#{i}", (i/3).ceil, col, false, '_')
You need to declare boxes = [] before the loop.
Then create your board from that list using ranges.
board = [boxes[1..3], boxes[4..6], boxes[7..9]]
And display_board becomes less repetitive.
def display_board(board)
board.each { |row|
row.each { |box|
box.display_box
}
puts "\n"
}
end
Finally, if you want to interpolate variables in strings you have to use ". For example, in display_box.
def display_box
print "|#{contents}|"
end
This is an error:
box#{i}
You can interpolate into Strings(and regexes), but a variable name is not a
String. A String has quotes around it.
Even if you could interpolate into variable names, you would never do this:
box#{i} = Box.new('box#{i}', (i/3).ceil, col, false, '_')
Instead, you would create an Array and add instances to the Array:
boxes = []
(1..9).each do |i|
if i > 3
col = i % 3
else
col = i
end
boxes << Box.new('box#{i}', (i/3).ceil, col, false, '_')
end
Then the names of your instances are boxes[0], boxes[1], etc.
You also need to know that a def creates a new scope and variables outside the def cannot be seen inside the def. So any box1, box2, etc. variables created outside the def cannot be seen inside the def. What you need to do is pass the boxes Array to the display_board() method, like this:
def display_board(board_boxes)
...
end
display_board(boxes)
Ruby then lines up your method call and the method header like this:
display_board(boxes)
|
V
def display_board(board_boxes)
and the boxes Array gets assigned to a variable called board_boxes:
board_boxes = boxes
Then inside the def, board_boxes will be the Array containing the boxes.
Don't combine lines of code on one line using semi colons. When you use an Array to store your box instances, you can display your boxes like this:
board_boxes.each do |box|
box.display_box
end
If you want to print a newline after every three boxes, you can do this:
count = 1
board_boxes.each do |box|
box.display_box
print "\n" if count%3 == 0
count += 1
end
You get undefined local variable or method `box1' because box1 is not defined.
Apparently, you expected this line to create box1:
box#{i} = ...
but it is really just this:
box
because # starts a comment.
Double-quotes strings allow interpolation, but you can't interpolate variable names like this.
How to solve it?
It is almost always a bad idea to create variables dynamically. If you have a large or a varying number of values, you should store them in a collection - either an Array, a Hash, or a custom one.
The box object
Setting up the boxes is quite complex, because you are passing name, row and column to each box. Does a box really have to know its position within the board? Think about other objects that are part of a larger structure: an array element doesn't know its index (the array does), a character doesn't know its position (the string does) and a hash value doesn't know its key (the hash does).
Let's remove these extra attributes from Box and have it just store its content:
class Box
attr_accessor :content
def initialize
#content = '_'
end
def marked?
content != '_'
end
end
b = Box.new #=> #<Box:0x007fab7a9f58a8 #content="_">
b.content #=> "_"
b.marked? #=> false
b.content = 'X'
b.marked? #=> true
The board object
To create a 3×3 array of boxes, we can write: (I've removed the object ids from the output)
board = Array.new(3) { Array.new(3) { Box.new } }
#=> [[#<Box #content="_">, #<Box #content="_">, #<Box #content="_">],
# [#<Box #content="_">, #<Box #content="_">, #<Box #content="_">],
# [#<Box #content="_">, #<Box #content="_">, #<Box #content="_">]]>
Single boxes can be accessed via: (indices are zero-based)
board[0][0] #=> #<Box #content="_">
But since board is such an important object, I'd write a custom class:
class Board
def initialize
#boxes = Array.new(3) { Array.new(3) { Box.new } }
end
def box(x, y)
#boxes[x][y]
end
end
The class does not expose #boxes, because we don't want the array to be changed. It provides a method Board#box instead that returns the box for the given x and y coordinates.
Formatting
In my opinion neither Box nor Board should contain code that handles formatting, so let's write a small utility class to handle this part:
class BoardFormatter
def draw(board)
template.gsub(/[0-8]/) do |n|
x, y = n.to_i.divmod 3
board.box(x, y).content
end
end
def template
<<-STR
0 | 1 | 2
---+---+---
3 | 4 | 5
---+---+---
6 | 7 | 8
STR
end
end
BoardFormatter#template returns the string for the board. You might not have seen <<- before: it's called a heredoc and creates a multiline string between the given STR delimiters:
formatter = BoardFormatter.new
formatter.template #=> " 0 | 1 | 2\n---+---+---\n 3 | 4 | 5\n---+---+---\n 6 | 7 | 8\n"
BoardFormatter#draw uses String#gsub to replace each digit ([0-8]) with the respective box' content.
divmod is the key here, it returns both, a / b and a % b as an array. And because we're using zero-based indices, these are just the box coordinates for the nth box:
0.divmod(3) #=> [0, 0]
1.divmod(3) #=> [0, 1]
2.divmod(3) #=> [0, 2]
3.divmod(3) #=> [1, 0]
4.divmod(3) #=> [1, 1]
5.divmod(3) #=> [1, 2]
6.divmod(3) #=> [2, 0]
7.divmod(3) #=> [2, 1]
8.divmod(3) #=> [2, 2]
Complete example:
board = Board.new
board.box(0, 2).content = 'X'
board.box(0, 0).content = 'O'
board.box(2, 0).content = 'X'
board.box(1, 1).content = 'O'
formatter = BoardFormatter.new
puts formatter.draw(board)
Output:
O | _ | X
---+---+---
_ | O | _
---+---+---
X | _ | _
One-based indices
The players should probably enter one-based indices when playing your game. This conversion should be handled when processing the user input. Within your core code, you should always use zero-based indices, just like Ruby.
As other users mentioned you can create an array to hold the instances of Box.
If you are dead set on using variables you can use instance_variable_set although using an array is probably better. See here for more details.
With instance_variable_set:
class Box
attr_reader :name, :row, :column
attr_accessor :is_marked, :contents
def initialize(name, row, column, is_marked=false, contents)
#name = name
#row = row
#column = column
#is_marked = is_marked
#contents = contents
end
def display_box
print '|#{contents}|'
end
end
#generate box instances
(1..9).each do |i|
if i > 3
col = i % 3
else
col = i
end
instance_variable_set("#box#{i}", Box.new('box#{i}', (i/3).ceil, col, false, '_'))
end
board = [[#box1, #box2, #box3], [#box4, #box5, #box6], [#box7, #box8, #box9]]
def display_board
#box1.display_box; #box2.display_box; #box3.display_box; print '\n'
#box4.display_box; #box5.display_box; #box6.display_box; print '\n'
#box7.display_box; #box8.display_box; #box9.display_box; print '\n'
end
display_board
With an array:
class Box
attr_reader :name, :row, :column
attr_accessor :is_marked, :contents
def initialize(name, row, column, is_marked=false, contents)
#name = name
#row = row
#column = column
#is_marked = is_marked
#contents = contents
end
def display_box
print '|#{contents}|'
end
end
#generate box instances
arr = [];
(1..9).each do |i|
if i > 3
col = i % 3
else
col = i
end
name = 'box' + i.to_s
arr.push(Box.new(name, (i/3).ceil, col, false, '_'))
end
board = [[arr[0], arr[1], arr[2]], [arr[3], arr[4], arr[5]], [arr[6], arr[7], arr[8]]]
def display_board(arr)
arr[0].display_box; arr[1].display_box; arr[2].display_box; print '\n'
arr[3].display_box; arr[4].display_box; arr[5].display_box; print '\n'
arr[6].display_box; arr[7].display_box; arr[8].display_box; print '\n'
end
display_board(arr)
Below is my take for the TicTacToe game. So far it works, but it's not perfect. I'm having an issue with one of the methods - Game#invalid_move_check? after the game asked you "where to:"once choose the new destination , the game change the symbol like if it was a new turn .in fact not , suppose to keep the same player symbol until next turn.
P.S the code probably need some refactoring. I'm in a learning phase.
class Game
def initialize(symbol)
#board = Array.new(3){Array.new(3)}
# [0,1,2]
# [3,4,5]
# [6,7,8]
#symbol = ["X", "O"]
end
WINNING_COMBO = [
# Horizontal wins:
[0, 1, 2], [3, 4, 5], [6, 7, 8],
# Vertical wins:
[0, 3, 6], [1, 4, 7], [2, 5, 8],
# Diagonal wins:
[0, 4, 8], [2, 4, 6]
]
def create_players
# create both players
#names = []
print "Please enter the name of the first player: "
#player_1 =gets.chomp
#names << #player_1
print "Please enter the name of the second player: "
#player_2 = gets.chomp
#names << #player_2
puts "\n"
puts"welcome #{#player_1.upcase} and #{#player_2.upcase}"
puts"------------------------------------------------"
puts"\n"
puts "Randomizing who'll start..."
puts"\n"
# assign player by calling the player_assigment function that will determine who will start first
player_assigment
puts"\n"
end
def player_assigment
# merge the names array and symbol array
# with the zip method and return a nested array with player and symbol.
#choice = #names.zip(#symbol)
# iterate over the choice nested array and
# print out each player and their assigned symbol
#choice.each do |player, symbol|
puts "#{player.upcase} will use #{symbol}"
end
end
def current
#current = #names.first
#current
end
def switch_turn
#current = #names.last
#current
end
def first_turn
current
puts "#{#current.upcase} turn"
#marker = #symbol.first
make_move(#marker)
end
def next_turn
switch_turn
puts "#{#current.upcase} turn"
#marker = #symbol.last
make_move(#marker)
end
def check_win?(first_arr, second_arr)
WINNING_COMBO.select do |item|
if
item == first_arr
puts"#{#player_1} won!!"
elsif
item == second_arr
puts "#{#player_2} won!!"
end
end
end
def mapping(move, marker)
case move
when 0
arr_index = 0
index = 0
invalid_move_check?(arr_index,index)
#board[0][0] = marker
when 1
arr_index = 0
index = 1
invalid_move_check?(arr_index,index)
#board[0][1] = marker
when 2
arr_index = 0
index = 2
invalid_move_check?(arr_index,index)
#board[0][2] = marker
when 3
arr_index = 1
index = 0
invalid_move_check?(arr_index,index)
#board[1][0] = marker
when 4
arr_index = 1
index = 1
invalid_move_check?(arr_index,index)
#board[1][1] = marker
when 5
arr_index = 1
index = 2
invalid_move_check?(arr_index,index)
#board[1][2] = marker
when 6
arr_index = 2
index = 0
invalid_move_check?(arr_index,index)
#board[2][0] = marker
when 7
arr_index = 2
index = 1
invalid_move_check?(arr_index,index)
#board[2][1] = marker
when 8
arr_index = 2
index = 2
invalid_move_check?(arr_index,index)
#board[2][2] = marker
end
end
def invalid
puts"move invalid"
end
def invalid_move_check?(arr_index, index)
array = #board
if array[arr_index][index] == "X" ||
array[arr_index][index] == "O"
invalid
puts "Where to :"
#move = gets.chomp.to_i
mapping(#move,#marker)
end
end
def make_move(marker)
# after each turn the make_move method will called to place move on the board
puts "Where to :"
#move = gets.chomp.to_i
mapping(#move,#marker)
print_board
end
# display board in a matrix format
def print_board
#board.each_slice(1) { |a| p a }
puts"\n"
end
def instructions
puts "Instructions :Enter your first move by entering a number 1-9"
puts "corresponding to the grid on the bottom and press enter"
puts"\n"
puts "0 | 1 | 2 ",
"----------",
"3 | 4 | 5 ",
"----------",
"6 | 7 | 8 "
print"\n"
end
def self.start(symbol)
# start a new game
new_game =Game.new(symbol)
# create players
new_game.create_players
new_game.instructions
new_game.print_board
# Checking wining combo for matching patter if none
while new_game.check_win?(#move_first, #move_second) do
new_game.first_turn
# the player switch turn
new_game.next_turn
end
end
loop do
puts"------------------------------------------------"
puts" Welcome to tictactoe ".upcase
puts"------------------------------------------------"
print"\n"
Game.start(#symbol)
end
end
This should do the trick:
#will return true or false to check validity of move
def invalid_move_check?(arr_index, index)
array = #board
if array[arr_index][index] == "X" ||
array[arr_index][index] == "O"
invalid
puts "Where to :"
#move = gets.chomp.to_i
mapping(#move,#marker)
return true
end
return false
end
def mapping(move, marker)
case move
...
when 0
arr_index = 0
index = 0
unless invalid_move_check?(arr_index,index) #change all cases
#board[0][0] = marker #to have the assignment of board
#only if the move is valid
end
...
end
end
The reason of your bug is that the assignment happens even if the move is invalid.
This is just a band-aid solution to your current problem, as for refactoring ,there are things that can be done to optimize your code and make it better :) But you still have to fix first your 'ending'. Refactoring your own code would be a very good practice. I wish you a joyful ruby journey
!
After scratching the previous code and rethink the code i 've come up with this solution , not elegant as i will want it to be but it works .i move the symbol assignment in the if/else block code and therefore when a move is invalid next move will use the symbol of the current player
def mapping(move, symbol)
case move
when 0
if #board[0][0]=="X" || #board[0][0] == "O"
invalid
make_move
else
#board[0][0] = symbol
track_move(#move)
print_board
end
...
end
end
This question already has an answer here:
How to input integer value to an array, based preceeding row + column values? [duplicate]
(1 answer)
Closed 8 years ago.
For this following project, I am supposed to take input in the following format : R1C5+2 , which reads it as "in the table, Row 1 Column 5 ,add 2. Or in this format : R1C2C3-5 , which reads : "in the table, Row 1 Column 2-3, subtract 5. This is assuming that all numbers in the table are initially all 0.
Where I left Off:
I am having trouble finding a way to detect for a "+" or "-" to either add/subtract values in the table. Also, in providing a range to allow multiple additions when provided two C's or R's. For example: R1R5C2C3+2 (Row Range 1 - 5, Column Range 2 - 3, add 2).
Here is the following code:
puts 'Please input: '
x = gets.chomp
col = []
row = []
x.chars.each_slice(2) { |u| u[0] == "R" ? row << u[1] : col << u[1] }
p col
p row
puts "Largest # in Row array: #{row.max}"
puts "Largest # in Columns array: #{col.max}" #must be in "" to return value
big_row = row.max.to_i
big_col = col.max.to_i
table = Array.new (big_row) { Array.new(big_col) }
I thank you all for the help!
You've accidentally posted this twice. Here is the answer I gave on the other copy:
The method you are looking for is the =~ operator. If you use it on a string and give it a regexp pattern it will return the location of that pattern in the string. Thus:
x = 'R1C2C3-5'
x =~ /R/
returns: 0 since that is the position of 'R' in the string (counted just like an array 0,1,2...).
If you are unfamiliar with regexp and the =~ operator, I suggest you check out the Ruby doc on it, it is very valuable. Basically the pattern between the forward slashes get matched. You are looking to match + or -, but they have special meaning in regexp, so you have to escape them with a backslash.
x =~ /\+/
x =~ /\-/
but you can combine those into one pattern matcher with an OR symbol (pipe) |
x =~ /\+|\-/
So now you have a method to get the operator:
def operator(my_string)
r = my_string.slice(my_string =~ /\+|\-/)
end
I would also use the operator to split your string into the column/row part and the numeric part:
op = operator(x) # which returns op = '-'
arr = x.split(my_string(x)) # which returns an array of two strings ['R1C2C3', '5']
I leave further string manipulation up to you. I would read through this page on the String class: Ruby String Class and this on arrays: Ruby Array Class as Ruby contains so many methods to make things like this easier. One thing I've learned to do with Ruby is think "I want to do this, I wonder if there is already a built in method to do this?" and I go check the docs. Even more so with Rails!
Your homework, sir.
puts 'Please input: '
x = gets.chomp
col = []
row = []
sign = ''
val = ''
x.chars.each_slice(2) do |u|
case u[0]
when 'R' then
row << u[1]
when 'C' then
col << u[1]
when '+', '-'
sign, val = u[0], u[1]
else
puts 'Invalid input.'
exit
end
end
big_row = row.max.to_i
big_col = col.max.to_i
table = Array.new (big_row) { Array.new(big_col) }
# Initialize table to all zeros
table.map! do |row|
row.map! { |col| 0 }
end
rows_range = row.length == 1 ? row[0]..row[0] : row[0]..row[1]
cols_range = col.length == 1 ? col[0]..col[0] : col[0]..col[1]
table.each_with_index do |row, ri|
if rows_range.include? (ri + 1).to_s
row.each_with_index do |col, ci|
if cols_range.include? (ci + 1).to_s
table[ri][ci] = (sign + val).to_i
end
end
end
end
# Padding for fields in table.
padding = 4
# Table
table.each do |row|
row.each do |col|
print "#{col.to_s.rjust(padding)}"
end
print "\n"
end
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
How can one generate a new list has all the elements of old-list except for some parts bracketted between line where f1(start_line) is true and f2(end_line) is true
Naive code
def remove_bracketted(orig_list)
ignore_flag = false
new_list = []
orig_list.each do |v|
if f1(v)
ignore_flag = true
elsif f2(v)
ignore_flag = false
else
new_list << v unless ignore_flag
end
end
end
For instance, with the following definitions of f1 and f2
def f1(v)
v == "{"
end
def f2(v)
v == "}"
end
when run on
foo(a,b)
{
s1
s2
s3
}
bar(a,b)
{
t1
t2
t3
}
Some other text
one should get
foo(a,b)
bar(a,b)
Some other text
Kindly note that f1 and f2 can be any function of type a -> Bool where list elements are all of type a and not just comparison to an open brace and close brace.
Edit:
I was looking for a solution like this which works if there is only one such pair
new_list = old_list.take_while(not(condition1)).concat(old_list.drop_while(not(condition2)))
This might be a place where the flip-flop operator would be useful:
def val1; '{' end
def val2; '}' end
p ['a','b','{','a','}','f','d','d'].reject{|x| true if (val1==x)..(val2==x)}
#=> ["a", "b", "f", "d", "d"]
p ['a','b','{','a','}','f','d','d'].select{|x| true if (val1==x)..(val2==x)}
#=> ["{", "a", "}"]
ScriptDevil, i guess some people won't like your way of making a question so i suggest asking it somewhat politer and not offer us a 'task' like we are in class. We are here to help and you should show us what you tried yourself.
Here is a way of doing what you want.
class String
def replace_between start, ending, replace_with
gsub(/#{start}[^#{ending}]*#{ending}/m, replace_with)
end
end
txt = %[
foo(a,b)
{
s1
s2
s3
}
bar(a,b)
{
t1
t2
t3
}
Some other text
]
puts txt.replace_between '{', '}', ''
# oo(a,b)
# bar(a,b)
# Some other text