Discuss Scratch
- Discussion Forums
- » Help with Scripts
- » Help with finding specific numbers in lists.
- GamingBucket
-
Scratcher
16 posts
Help with finding specific numbers in lists.
Hello!
I am working on a game, and am struggling to think of a system that when given a number, returns a closest number to it from a list. For example:
I am given the number 5,
There is a list with the numbers
1,3,9,12
It should return 3, as it is the closest to 5.
Is there any way to do that in an efficient way?
Thank you for your time.
I am working on a game, and am struggling to think of a system that when given a number, returns a closest number to it from a list. For example:
I am given the number 5,
There is a list with the numbers
1,3,9,12
It should return 3, as it is the closest to 5.
Is there any way to do that in an efficient way?
Thank you for your time.
- HighlaneGamingStudio
-
Scratcher
500+ posts
Help with finding specific numbers in lists.
Hello!Efficient? No, but there is a way:
I am working on a game, and am struggling to think of a system that when given a number, returns a closest number to it from a list. For example:
I am given the number 5,
There is a list with the numbers
1,3,9,12
It should return 3, as it is the closest to 5.
Is there any way to do that in an efficient way?
Thank you for your time.
define find closest value to (number) from listIf the comments are cut off, comment 1 says “All ()+() blocks below can be changed to ()-() if you would like the output to round down instead of up,” and comment 2 says “The variable ”round“ is used as the output. This can be a separate variable.”
set [round v] to [0]
repeat until <<[list v] contains ((number::custom) - (round)) ?> or <[list v] contains ((number::custom) + (round)) ?>>
change [round v] by (1)
end
if <[list v] contains ((number::custom) + (round)) ?> then //All ()+() blocks below can be changed to ()-() if you would like the output to round down instead of up.
set [round v] to (item # of ((number::custom) + (round)) in [list v])//The variable "round" is used as the output. This can be a separate variable.
else
set [round v] to (item # of ((number::custom) - (round)) in [list v])
end
Last edited by HighlaneGamingStudio (Feb. 10, 2025 21:15:19)
- GamingBucket
-
Scratcher
16 posts
Help with finding specific numbers in lists.
This looks like about something I was thinking about! Much better than I could have done, thank you.
- awesome-llama
-
Scratcher
1000+ posts
Help with finding specific numbers in lists.
HighlaneGamingStudio's solution can be very inefficient because of the number of times the list needs to be searched if the numbers aren't close. Every use of the contains block needs to search the entire list. It also fails on cases where the numbers aren't integers.
There is a way to solve all this and only need to loop over the list once:
The reason why the first item is skipped is because we need a number to begin making comparisons with. We can assume the closest number has a distance at least the distance from the first.
The “abs” (short for absolute value) block converts all numbers into positive numbers. When the subtraction between list item and inputted number is made, the result is either positive or negative. We only want to know the “distance” between the two numbers and do not want to know which direction it is, hence the conversion into positive distances only.
The resulting closest number can then be retrieved with the “closest index” variable.
There is a way to solve all this and only need to loop over the list once:
define find closest value to (number)
set [closest index v] to [1] // stores which item number is the closest
set [closest distance v] to ([abs v] of ((item (1) of [list v] :: list) - (number))::operators)
set [i v] to [2] // counter to start on the second item (see comment below the script)
repeat ((length of [list v] :: list) - (1)) // search every item (except the first, see comment below the script)
if <([abs v] of ((item (i) of [list v] :: list) - (number))::operators) < (closest distance)> then // check if current item is closer
set [closest index v] to (i) // update closest index to the current item because it is closer
set [closest distance v] to ([abs v] of ((item (i) of [list v] :: list) - (number))::operators)
end
change [i v] by (1) // increase counter to go to the next item
end
The reason why the first item is skipped is because we need a number to begin making comparisons with. We can assume the closest number has a distance at least the distance from the first.
The “abs” (short for absolute value) block converts all numbers into positive numbers. When the subtraction between list item and inputted number is made, the result is either positive or negative. We only want to know the “distance” between the two numbers and do not want to know which direction it is, hence the conversion into positive distances only.
The resulting closest number can then be retrieved with the “closest index” variable.
(item (closest index) of [list v] :: list)
Last edited by awesome-llama (Feb. 11, 2025 00:15:38)
- HighlaneGamingStudio
-
Scratcher
500+ posts
Help with finding specific numbers in lists.
We only want to know the “distance” between the two numbers and do not want to know which direction it is, hence the conversion into positive distances only.I think you're misunderstanding the question. We don't want to know the distance between the numbers, we want the closest number to the input from the list. Your solution gets the difference of to the closest value in the list to the input.
Last edited by HighlaneGamingStudio (Feb. 10, 2025 22:34:14)
- awesome-llama
-
Scratcher
1000+ posts
Help with finding specific numbers in lists.
When I said distance between the numbers, I meant distance between each the item numbers with the input number.We only want to know the “distance” between the two numbers and do not want to know which direction it is, hence the conversion into positive distances only.I think you're misunderstanding the question. We don't want to know the distance between the numbers, we want the closest number to the input from the list. Your solution gets the difference of to the closest value in the list to the input.
I'm not finding the distance between list items.
Edited my original reply to make it easier to understand.
Last edited by awesome-llama (Feb. 10, 2025 22:57:24)
- HighlaneGamingStudio
-
Scratcher
500+ posts
Help with finding specific numbers in lists.
That's not solving the problem either- what I think GamingBucket is asking for is finding CLOSEST NUMBER in the list to the input value. The ideal block would look like this:When I said distance between the numbers, I meant distance between each the item numbers with the input number.We only want to know the “distance” between the two numbers and do not want to know which direction it is, hence the conversion into positive distances only.I think you're misunderstanding the question. We don't want to know the distance between the numbers, we want the closest number to the input from the list. Your solution gets the difference of to the closest value in the list to the input.
I'm not finding the distance between list items.
item closest in numerical value to [] in [list v]::list reporterIf the list had the numbers 1, 3, 9, and 12, and the input was 5, like in GamingBucket's example, the number in that list closest to 5 is 3. The reporter would return 3 because it is closest to 5. What's reported is not the distance from something to something, it's the closest value numerically to the input, 5. Since that block doesn't exist, we're making a workaround that reports the same value. In my block, it would work like this:
repeat until <<[list v] contains (5) ?> or <[list v] contains (5) ?>>This section is checking for the same number, 5, to see if it matches any item in the list. Since the list doesn't have 5 on it, the variable round is increased by 1, causing this section to run like this:
change [round v] by (1)
end
repeat until <<[list v] contains (4) ?> or <[list v] contains (6) ?>>Again, since the list contains neither of those values, we move on to the next round:
change [round v] by (1)
end
repeat until <<[list v] contains (3) ?> or <[list v] contains (7) ?>>Bingo! The list contains 3, so the loop stops with variable round at 2. Now, to find out which number caused the loop to stop, this if block runs:
change [round v] by (1)
end
if <[list v] contains (7) ?> thenI will note that I forgot to include this block at the end to convert the item number to the value:
set [round v] to (item # of (7) in [list v])
else
set [round v] to (item # of (3) in [list v])
end
set [round v] to (item (round) of [list v] :: list)
Here's what you did, assuming the input is 5:
set [closest index v] to [1]Can you explain what this is returning and how it both solves the original problem and makes it more efficient at the same time?
set [closest distance v] to ([abs v] of ((item (1) of [list v] :: list) - (5))::operators)
set [i v] to [2]
repeat ((length of [list v] :: list) - (1))
if <([abs v] of ((item (2) of [list v] :: list) - (5))::operators) < (1)> then
set [closest index v] to (2)
set [closest distance v] to ([abs v] of ((item (2) of [list v] :: list) - (5))::operators)
end
change [i v] by (1)
end
- awesome-llama
-
Scratcher
1000+ posts
Help with finding specific numbers in lists.
Can you explain what this is returning and how it both solves the original problem and makes it more efficient at the same time?I don't have the time to go step-by-step through my script.
I will clarify that to get the resulting closest number from my script, use:
(item (closest index) of [list v] :: list)The closest distance variable can be ignored, it's only used in the script to help find which item is the closest.
I've implemented this script (or variations of it) many times before. I know it works.
Last edited by awesome-llama (Feb. 11, 2025 00:21:18)
- EpicGhoul993
-
Scratcher
1000+ posts
Help with finding specific numbers in lists.
Can you explain what this is returning
set [closest index v] to [2] //2 is placeholder # for iLlama's not directly returning the number, but an index.
and how it both solves the original problem and makes it more efficient at the same timeLlama's code goes through the list only once. Your code, while more block space efficient (the list contains block is doing heavy lifting here), has to scan the list multiple times, due to the list contains block scanning the whole list each time it is ran.
- HighlaneGamingStudio
-
Scratcher
500+ posts
Help with finding specific numbers in lists.
I know, I was simplifying the code to say what it was returning the first time it was run.Can you explain what this is returningset [closest index v] to [2] //2 is placeholder # for iLlama's not directly returning the number, but an index.
I get it now. Thank's for clarifying, I thought the variable that was being returned was closest distance, not closest index.Can you explain what this is returning and how it both solves the original problem and makes it more efficient at the same time?I don't have the time to go step-by-step through my script.
I will clarify that to get the resulting closest number from my script, use:(item (closest index) of [list v] :: list)The closest distance variable can be ignored, it's only used in the script to help find which item is the closest.
I've implemented this script (or variations of it) many times before. I know it works.
- GamingBucket
-
Scratcher
16 posts
Help with finding specific numbers in lists.
Thank you all (Especially Llama) For Your help, I couldn't have done this without You.
Ill be sure to credit You all in the final product!
Ill be sure to credit You all in the final product!
- Frozn_PRO
-
Scratcher
2 posts
Help with finding specific numbers in lists.
Hi! I am in this discussion because I am having trouble with the block below. It keeps on getting a weird and wrong estimate like 3 or 2 when it is clearly 12. SOMEONE PLEASE HELP!!! 

(item ( v) of [list v] :: list)
- cheddargirl
-
Scratch Team
1000+ posts
Help with finding specific numbers in lists.
Hi! I am in this discussion because I am having trouble with the block below. It keeps on getting a weird and wrong estimate like 3 or 2 when it is clearly 12. SOMEONE PLEASE HELP!!!It would be best to create a new topic for yourself instead of posting in someone else's old thread, as this makes it easier to receive assistance from others.(item ( v) of [list v] :: list)

- Discussion Forums
- » Help with Scripts
-
» Help with finding specific numbers in lists.