<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Roman</title><subtitle>I study in Prague, love programming</subtitle><author><name>Roman</name></author><id>https://teletype.in/atom/rastr_0</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/rastr_0?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@rastr_0?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=rastr_0"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/rastr_0?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-16T09:02:53.381Z</updated><entry><id>rastr_0:ray-casting</id><link rel="alternate" type="text/html" href="https://teletype.in/@rastr_0/ray-casting?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=rastr_0"></link><title>Ray-casting with Pygame</title><published>2023-01-20T01:14:49.664Z</published><updated>2023-01-20T01:14:49.664Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/a2/cc/a2cc125f-3132-4e45-bd39-2f15cc7d2a0c.png"></media:thumbnail><category term="algorithms" label="Algorithms"></category><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/47/a0/47a0c079-d1a1-4ae4-80d1-99ff13c7a268.png&quot;&gt;Hi there, in this article I'm going to discuss ray-casting theme and create raycasting algorithm from the scratch with pygame.</summary><content type="html">
  &lt;p id=&quot;dL4o&quot;&gt;Hi there, in this article I&amp;#x27;m going to discuss ray-casting theme and create raycasting algorithm from the scratch with pygame.&lt;/p&gt;
  &lt;p id=&quot;MqJZ&quot;&gt;You could find following topics:&lt;/p&gt;
  &lt;ul id=&quot;KzYt&quot;&gt;
    &lt;li id=&quot;5TAE&quot;&gt;Theory about ray-casting and when was firstly used.&lt;/li&gt;
    &lt;li id=&quot;c8ha&quot;&gt;Implementation with pygame&lt;/li&gt;
  &lt;/ul&gt;
  &lt;ol id=&quot;Wxfw&quot;&gt;
    &lt;li id=&quot;aGyv&quot;&gt;Drawing map&lt;/li&gt;
    &lt;li id=&quot;FrUM&quot;&gt;Ray-casting algorithm implementation on 2D map&lt;/li&gt;
    &lt;li id=&quot;m4Mv&quot;&gt;3D implementation&lt;/li&gt;
    &lt;li id=&quot;WZMh&quot;&gt;Collision detection&lt;/li&gt;
    &lt;li id=&quot;Pua0&quot;&gt;Displating FPS&lt;/li&gt;
  &lt;/ol&gt;
  &lt;ul id=&quot;fEnH&quot;&gt;
    &lt;li id=&quot;rqMI&quot;&gt;Perfomance considerations&lt;/li&gt;
    &lt;li id=&quot;SEO2&quot;&gt;Resources&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;zkUb&quot; data-align=&quot;center&quot;&gt;Theory about ray-casting&lt;/h3&gt;
  &lt;p id=&quot;gyNB&quot;&gt;Raycasting is a rendering technique to create a 3D perspective in a 2D map. People came up to the idea of using raycasting in that time, when computers were way slow (early 90-s) to run a 3D engines in a realtime. The most famouse game, which uses raycasting is Wolfenstein 3D, released back in 1992. The basic idea behind raycasting is to trace rays from the &amp;#x27;eye&amp;#x27; and find the closest object blocking the path of that ray. We need try to increase the length of a ray at each step of the loop and if ray does hit the wall, then ray ends at this point. This processing should be done with each ray, it could be 30 or 300, depends on needs.&lt;/p&gt;
  &lt;figure id=&quot;Lspo&quot; class=&quot;m_retina&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/47/a0/47a0c079-d1a1-4ae4-80d1-99ff13c7a268.png&quot; width=&quot;298&quot; /&gt;
    &lt;figcaption&gt;Example with 30 rays and pi/3 FOV&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;XGts&quot; data-align=&quot;center&quot;&gt;More theory&lt;/h3&gt;
  &lt;p id=&quot;2ldl&quot;&gt;As you could notice in ray-casting algorithm we need to use FOV(filed of view) for further simulating 3D. FOV determines where player&amp;#x27;s visible range begins and ends. Usually in games FOV is equal to 60% or &lt;em&gt;pi&lt;/em&gt;/3. You could change FOV value and have a look at results.&lt;/p&gt;
  &lt;figure id=&quot;Q4xx&quot; class=&quot;m_retina&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/56/d8/56d828b9-9b3d-48b7-ad45-b6407a605285.png&quot; width=&quot;298.5&quot; /&gt;
    &lt;figcaption&gt;Example with 30 rays and pi/6 FOV&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ejWQ&quot;&gt;The process of generating rays in FOV range is not hard at all. There are just a few formulas behind it.&lt;/p&gt;
  &lt;p id=&quot;MZ8Z&quot;&gt;The angle of the first ray will determined in the next way:  &lt;/p&gt;
  &lt;p id=&quot;1JSo&quot;&gt;&lt;em&gt;&lt;strong&gt;starting_angle = player_angle - FOV / 2&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
  &lt;p id=&quot;tBxN&quot;&gt;And formula for finding distance between two angles:&lt;/p&gt;
  &lt;p id=&quot;Nne1&quot;&gt;&lt;strong&gt;&lt;em&gt;delta_angle = FOV / number_of_rays&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;HflO&quot; class=&quot;m_custom&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/eb/d3/ebd3b78a-f056-49cc-9364-b112b439cc63.jpeg&quot; width=&quot;381.41361256544496&quot; /&gt;
    &lt;figcaption&gt;Circle with angles labels&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;E02G&quot;&gt;Let&amp;#x27;s substitute the values in our first quation. Player_angle is &lt;strong&gt;&lt;em&gt;pi &lt;/em&gt;&lt;/strong&gt;and FOV / 2 is &lt;strong&gt;&lt;em&gt;((pi/3)/2)&lt;/em&gt;&lt;/strong&gt;. Starting_angle equal to &lt;strong&gt;&lt;em&gt;(5pi)/6&lt;/em&gt;&lt;/strong&gt; which is right in the upper left quadrant. If you have a look at the first screenshot, you could notice, that (5pi)/6 is exact dot where FOV starts.&lt;/p&gt;
  &lt;p id=&quot;Avxw&quot;&gt;I think for &lt;strong&gt;&lt;em&gt;delta_angle&lt;/em&gt;&lt;/strong&gt; no explanations needed, it&amp;#x27;s really simple.&lt;/p&gt;
  &lt;h3 id=&quot;6hIq&quot; data-align=&quot;center&quot;&gt;Drawing map&lt;/h3&gt;
  &lt;p id=&quot;aodW&quot;&gt;Now I want to provide code that draws map, player, FOV and we&amp;#x27;ll be back again to a few formulas to compute points of intersection with walls.&lt;/p&gt;
  &lt;pre id=&quot;DCJ3&quot; data-lang=&quot;python&quot;&gt;import pygame
import sys
import math

#global constants
SCREEN_HEIGHT = 480
SCREEN_WIDTH = SCREEN_HEIGHT * 2
MAP_SIZE = 8
TILE_SIZE = int((SCREEN_WIDTH / 2) / MAP_SIZE)
FOV = math.pi / 3
HALF_FOV = FOV / 2
CASTED_RAYS = 30

#global variables
player_x = (SCREEN_WIDTH / 2) / 2
player_y = (SCREEN_WIDTH / 2) / 2
player_angle = math.pi

MAP = (&amp;#x27;########&amp;#x27;
       &amp;#x27;# #    #&amp;#x27;    
       &amp;#x27;# #  ###&amp;#x27;    
       &amp;#x27;#      #&amp;#x27;   
       &amp;#x27;##     #&amp;#x27;   
       &amp;#x27;#  ### #&amp;#x27;   
       &amp;#x27;#   #  #&amp;#x27;  
       &amp;#x27;########&amp;#x27;)

#game window
pygamepygame.init()
win = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption(&amp;#x27;Ray-casting&amp;#x27;)
clock = pygame.time.Clock()

#game loop
while True:    
    for event in pygame.event.get():        
        if event.type == pygame.QUIT:            
            pygame.quit()
            sys.exit(0)
    
    draw_map()
    
    #update display    
    pygame.display.flip()
    
    #set FPS    
    clock.tick(30)&lt;/pre&gt;
  &lt;p id=&quot;aMdx&quot;&gt;I defined global constants, variables, map and wrote minimum framework for creating a window in pygame. Let&amp;#x27;s dive into &lt;strong&gt;&lt;em&gt;draw_map&lt;/em&gt;&lt;/strong&gt; function&lt;/p&gt;
  &lt;p id=&quot;om78&quot;&gt;The idea behind creating map is simple as hell. We need to iterate over two-dimensional array and compute square index, then create tiles with correspoding color (wall or not). &lt;/p&gt;
  &lt;pre id=&quot;gyTy&quot; data-lang=&quot;python&quot;&gt;def draw_map():    
    #colors
    light_grey = (191, 191, 191)
    dark_grey = (65, 65, 65)
    
    #iterate over map    
    for i in range(MAP_SIZE):
        for j in range(MAP_SIZE):            
            #calculate square index            
            square = i * MAP_SIZE + j
            
            #draw map            
            pygame.draw.rect(win, 
                light_grey if MAP[square] == &amp;#x27;#&amp;#x27; else dark_grey,                
                (j * TILE_SIZE, i * TILE_SIZE, TILE_SIZE - 1, TILE_SIZE - 1))&lt;/pre&gt;
  &lt;p id=&quot;VxMW&quot;&gt;The reason why I increase 1 from &lt;strong&gt;&lt;em&gt;TILE_SIZE&lt;/em&gt;&lt;/strong&gt; is because it just looks better, we got nice-looking grid on the map.&lt;/p&gt;
  &lt;figure id=&quot;kYhW&quot; class=&quot;m_retina&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/1b/19/1b19fad5-174a-429f-89d1-de3fe52e62ac.png&quot; width=&quot;299&quot; /&gt;
    &lt;figcaption&gt;Map without stripes&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;07Ib&quot; class=&quot;m_retina&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/18/1f/181fcb08-117e-4c20-9823-60cc226f9790.png&quot; width=&quot;298&quot; /&gt;
    &lt;figcaption&gt;Map with stripes&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;HtyV&quot;&gt;Map is ready, now need to add player. This code is continuation of &lt;strong&gt;&lt;em&gt;draw_map&lt;/em&gt;&lt;/strong&gt; function.&lt;/p&gt;
  &lt;pre id=&quot;yNk9&quot; data-lang=&quot;python&quot;&gt;#draw player    
pygame.draw.circle(win, (162, 0, 255), (int(player_x), int(player_y)), 12)&lt;/pre&gt;
  &lt;h3 id=&quot;sCTg&quot; data-align=&quot;center&quot;&gt;Ray-casting implementation&lt;/h3&gt;
  &lt;p id=&quot;bMvS&quot;&gt;Now the most interesting part: implementation of ray-casting algorithm&lt;/p&gt;
  &lt;p id=&quot;rLeY&quot;&gt;The idea is to firstly get target &lt;strong&gt;&lt;em&gt;x&lt;/em&gt;&lt;/strong&gt; and &lt;em&gt;target &lt;strong&gt;y&lt;/strong&gt;&lt;/em&gt; coorditanes and then to convert that coordinates to column and row. Then, with column and row, get square index and with square index it&amp;#x27;s really simple to check if it&amp;#x27;s a wall or nothing (do we need to cast the ray or not). Of course the set of this operations should be done with each ray.&lt;/p&gt;
  &lt;pre id=&quot;Lfbt&quot; data-lang=&quot;python&quot;&gt;for ray in range(CASTED_RAYS):        
    for depth in range(MAX_DEPTH):            
        #get ray target coordinates            
        target_x = player_x - math.sin(start_angle) * depth
        target_y = player_y +  math.cos(start_angle) * depth
        
        #convert target x, y coordinates to map col, row
        col = int(target_x / TILE_SIZE)           
        row = int(target_y / TILE_SIZE)  
        
        #calculate map square index            
        square = row * MAP_SIZE + col                        
        
        #print(square)
        if MAP[square] == &amp;#x27;#&amp;#x27;:                
            pygame.draw.rect(win, (195, 137, 38), 
                            (col * TILE_SIZE, row * TILE_SIZE, 
                            TILE_SIZE - 1, TILE_SIZE - 1))                                
            
            #draw casted ray                
            pygame.draw.line(win, (233, 166, 49), (player_x, player_y), (target_x, target_y))                                
            break
        
        #increment angle by step        
        start_angle += STEP_ANGLE&lt;/pre&gt;
  &lt;p id=&quot;5snG&quot;&gt;Movement of the player and updating background. With using &lt;strong&gt;&lt;em&gt;cos &lt;/em&gt;&lt;/strong&gt;and &lt;strong&gt;&lt;em&gt;sin&lt;/em&gt;&lt;/strong&gt; functions we can move player in &lt;strong&gt;&lt;em&gt;x&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;y &lt;/em&gt;&lt;/strong&gt;directions. Feel free to experement with signs of numbers or math functions to observe how it all works.&lt;/p&gt;
  &lt;pre id=&quot;8ikD&quot; data-lang=&quot;python&quot;&gt;#update background    
pygame.draw.rect(win, (0, 0, 0), (0, 0, SCREEN_HEIGHT, SCREEN_HEIGHT))

#get user input    
keys = pygame.key.get_pressed()

#handle user input    
if keys[pygame.K_LEFT]:        
    #working with radians, not degrees       
    player_angle -= 0.1
elif keys[pygame.K_RIGHT]:        
    player_angle += 0.1    
elif keys[pygame.K_UP]:        
    player_x += -1 * math.sin(player_angle) * 5        
    player_y += math.cos(player_angle) * 5    
elif keys[pygame.K_DOWN]:        
    player_x -= -1 * math.sin(player_angle) * 5        
    player_y -= math.cos(player_angle) * 5
    &lt;/pre&gt;
  &lt;h3 id=&quot;f26F&quot; data-align=&quot;center&quot;&gt;Time for 3D&lt;/h3&gt;
  &lt;p id=&quot;Uc2K&quot;&gt;The idea is simple and beatiful. We need to estimate length untill wall and depending on results build wall with relevant size and color.&lt;/p&gt;
  &lt;p id=&quot;tRav&quot;&gt;The are two things which affect to building a 3D wall, first is what size it should be and second what color wall should be(from white to black).&lt;/p&gt;
  &lt;pre id=&quot;ekWc&quot; data-lang=&quot;python&quot;&gt;#wall shading                
color = 255 / (1 + depth * depth * 0.0001)

#calculate wall height
wall_height = 21000 / (depth + 0.0001)&lt;/pre&gt;
  &lt;p id=&quot;EKPS&quot;&gt;Color formula is easy, further is player darker is color. Wall height formula also is a piece of cake. Instead of &lt;strong&gt;&lt;em&gt;21000&lt;/em&gt;&lt;/strong&gt; could be any other big number, you can experiment with this variable and get right result for your needs.&lt;/p&gt;
  &lt;figure id=&quot;rLGt&quot; class=&quot;m_retina&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c1/24/c124fb56-a885-4f54-b355-8471d458b445.png&quot; width=&quot;597&quot; /&gt;
    &lt;figcaption&gt;Example with value 21k&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;GGPt&quot; class=&quot;m_retina&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d0/d8/d0d85ddf-285f-4c69-9f5b-ddfde18d44ed.png&quot; width=&quot;598.5&quot; /&gt;
    &lt;figcaption&gt;Example with value 17k instead of 21k&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;nPBs&quot;&gt;SCALE constant should be added to &amp;quot;global constants&amp;quot; part of the code with following code, below you will find out why it&amp;#x27;s important:&lt;/p&gt;
  &lt;pre id=&quot;MOIs&quot; data-lang=&quot;python&quot;&gt;SCALE = (SCREEN_WIDTH / 2) / CASTED_RAYS&lt;/pre&gt;
  &lt;pre id=&quot;yZOB&quot; data-lang=&quot;python&quot;&gt;#draw 3D projection
pygame.draw.rect(win, (color, color, color),
                (SCREEN_HEIGHT + ray * SCALE,
                (SCREEN_HEIGHT / 2) - wall_height / 2, SCALE, wall_height))                &lt;/pre&gt;
  &lt;p id=&quot;Iq3E&quot;&gt;This code draws wall with appropriate size, color and scale. But how it works in details? Actually we create a lot of vertical stripes with the same width(&lt;strong&gt;&lt;em&gt;SCALE&lt;/em&gt;&lt;/strong&gt; value) and shifting next stripe exactly on the SCALE value, that&amp;#x27;s why SCALE value is really important(sorry for the tautology). &lt;/p&gt;
  &lt;p id=&quot;SjRI&quot;&gt;Updating 3D background for upper and lower part of the screen.&lt;/p&gt;
  &lt;pre id=&quot;iW3B&quot; data-lang=&quot;python&quot;&gt;#update 3D background    
pygame.draw.rect(win, (100, 100, 100), (480, SCREEN_HEIGHT / 2, SCREEN_HEIGHT, SCREEN_HEIGHT))    
pygame.draw.rect(win, (200, 200, 200), (480, -SCREEN_HEIGHT / 2, SCREEN_HEIGHT, SCREEN_HEIGHT))&lt;/pre&gt;
  &lt;p id=&quot;IC77&quot;&gt;Now we got a few things to finish in project: create collision detection with walls and display FPS.&lt;/p&gt;
  &lt;h3 id=&quot;6B25&quot; data-align=&quot;center&quot;&gt;Collision detection&lt;/h3&gt;
  &lt;p id=&quot;y6z1&quot;&gt;The same tactic which we use in ray_casting function but in place of rays coordinate we use players coordinates for detection collisions with walls.nvert player x, y coordinates to map col, row    &lt;br /&gt;col = int(player_x / TILE_SIZE)    &lt;br /&gt;row = int(player_y / TILE_SIZE)  &lt;br /&gt;&lt;br /&gt;#calculate map square index    &lt;br /&gt;square = row * MAP_SIZE + col&lt;br /&gt;&lt;br /&gt;# player hits the wall (collision detection)    &lt;br /&gt;if MAP[square] == &amp;#x27;#&amp;#x27;:         &lt;br /&gt;    if forward:            &lt;br /&gt;        player_x -= -1 * math.sin(player_angle) * 5            &lt;br /&gt;        player_y -= math.cos(player_angle) * 5       &lt;br /&gt;    else:            &lt;br /&gt;        player_x += -1 * math.sin(player_angle) * 5            &lt;br /&gt;        player_y += math.cos(player_angle) * 5&lt;/p&gt;
  &lt;h3 id=&quot;J3VJ&quot; data-align=&quot;center&quot;&gt;Displaying FPS&lt;/h3&gt;
  &lt;p id=&quot;KDTM&quot;&gt;Nothing interesting what we really should talk about. &lt;strong&gt;&lt;em&gt;SCREEN_WIDTH / 2&lt;/em&gt;&lt;/strong&gt; is going to display FPS counter right in the left corner of 3D projection.&lt;/p&gt;
  &lt;pre id=&quot;k2br&quot; data-lang=&quot;python&quot;&gt;#set FPS    
fps = str(int(clock.get_fps()))    
font = pygame.font.SysFont(&amp;#x27;Arial&amp;#x27;, 30)    
fpssurface = font.render(fps, False, (255, 255, 255))    
win.blit(fpssurface, (int(SCREEN_WIDTH / 2), 0))&lt;/pre&gt;
  &lt;h3 id=&quot;muRp&quot; data-align=&quot;center&quot;&gt;Perfomance considerations&lt;/h3&gt;
  &lt;p id=&quot;JYLZ&quot;&gt;Ray-casting, in fact, works slower than modern 3D engines getting rendered on our super quick computers with using 3D graphics cards. There are at least 2 big issues with this code.&lt;/p&gt;
  &lt;ul id=&quot;p5wI&quot;&gt;
    &lt;li id=&quot;8SWC&quot;&gt;The way how we find interaction with wall is not optimized at all. What we do is just sorting through dots to the wall, by comparing each dot with wall boundary. There are a way out! Using DDA(Digital Differential Analysis). DDA is a fast algorithm typically used on square grids to find which square line hits. &lt;a href=&quot;https://www.youtube.com/watch?v=NbSee-XM7WA&quot; target=&quot;_blank&quot;&gt;Javidx9&lt;/a&gt; got fascinating material about this.&lt;/li&gt;
    &lt;li id=&quot;r6zF&quot;&gt;Ray-casting works with vertical stripes, when our screen buffers were build to work with horizontal stripes. So, when we draw vertical stripe it is the worst scenario for memory locality. And this causes a lot of problems with speed. You may try to find interesting content about this.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;AGmS&quot; data-align=&quot;center&quot;&gt;Resources&lt;/h3&gt;
  &lt;p id=&quot;Guit&quot;&gt;I came to the conclusion that any work can be considered as &amp;quot;serious&amp;quot; if it does not have link to resources, so in the future I will always try to add them.&lt;/p&gt;
  &lt;ul id=&quot;jgyo&quot;&gt;
    &lt;li id=&quot;lEtT&quot;&gt;&lt;a href=&quot;https://lodev.org/cgtutor/raycasting.html&quot; target=&quot;_blank&quot;&gt;https://lodev.org/cgtutor/raycasting.html&lt;/a&gt; (eng)&lt;/li&gt;
    &lt;li id=&quot;H6wz&quot;&gt;&lt;a href=&quot;https://killerrobotics.me/2021/08/13/raycasting-game-in-python-and-pygame-part-1/comment-page-1/&quot; target=&quot;_blank&quot;&gt;https://killerrobotics.me/2021/08/13/raycasting-game-in-python-and-pygame-part-1/comment-page-1/&lt;/a&gt; (eng)&lt;/li&gt;
    &lt;li id=&quot;fYR1&quot;&gt;&lt;a href=&quot;https://permadi.com/1996/05/ray-casting-tutorial-table-of-contents/&quot; target=&quot;_blank&quot;&gt;https://permadi.com/1996/05/ray-casting-tutorial-table-of-contents/&lt;/a&gt; (old but still can get understanding how things work) (eng)&lt;/li&gt;
    &lt;li id=&quot;ETtC&quot;&gt;&lt;a href=&quot;https://replit.com/talk/ask/Move-a-sprite-at-an-angle-in-pygame/130940&quot; target=&quot;_blank&quot;&gt;https://replit.com/talk/ask/Move-a-sprite-at-an-angle-in-pygame/130940&lt;/a&gt; (topic about movement player) (eng)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;0Ynp&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;WmNQ&quot;&gt;GitHub code: &lt;a href=&quot;https://github.com/rastr-0/teletype_source_files/blob/main/ray-casting/ray-casting.py&quot; target=&quot;_blank&quot;&gt;https://github.com/rastr-0/teletype_source_files/blob/main/ray-casting/ray-casting.py&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;dMaI&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;7J2Y&quot; data-align=&quot;right&quot;&gt;See ya soon&lt;/p&gt;
  &lt;p id=&quot;C7Ut&quot; data-align=&quot;right&quot;&gt;@rastr&lt;/p&gt;

</content></entry><entry><id>rastr_0:hash_tables</id><link rel="alternate" type="text/html" href="https://teletype.in/@rastr_0/hash_tables?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=rastr_0"></link><title>Hash tables</title><published>2022-12-19T11:14:19.049Z</published><updated>2022-12-19T13:16:24.080Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/ce/37/ce37e9ce-afc0-44da-8d70-884ad8c62a0f.png"></media:thumbnail><category term="algorithms" label="Algorithms"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/75/7c/757c8b08-844e-4386-af2c-792b9fbece63.jpeg&quot;&gt;Hi there, in this article I want to talk about hash tables and implement it with c++, let's get started.</summary><content type="html">
  &lt;p id=&quot;1Pfg&quot;&gt;Hi there, in this article I want to talk about hash tables and implement it with c++, let&amp;#x27;s get started.&lt;/p&gt;
  &lt;p id=&quot;ob6j&quot;&gt;Hash table is data structure that implements an associative array. Hash tables use hash function to compute an index, which makes them really fast in finding elements. Because of this they&amp;#x27;re widely used in comuter software.&lt;/p&gt;
  &lt;figure id=&quot;UsgR&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/75/7c/757c8b08-844e-4386-af2c-792b9fbece63.jpeg&quot; width=&quot;473&quot; /&gt;
    &lt;figcaption&gt;Hash table&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;6AaM&quot;&gt;I&amp;#x27;ll define HashTable class to implement data structure. Here you can see definition of the main functions of class.&lt;/p&gt;
  &lt;pre id=&quot;eMSl&quot; data-lang=&quot;cpp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;list&amp;gt;
#include &amp;lt;string&amp;gt; 

class HashTable{
private: 
    static const int hash_groups = 1000;
    static const int lower_limit = 1;
    static const int upper_limit = 100000;
     
    std::list&amp;lt;std::pair&amp;lt;int, std::string&amp;gt;&amp;gt; table[hash_groups];
public:
    void insert_item(const int key, const std::string&amp;amp; value);
    void remove_item(const int key);
    bool is_empty() const;
    const int hash_function(const int key);
    void print();&lt;/pre&gt;
  &lt;h2 id=&quot;ezOQ&quot; data-align=&quot;center&quot;&gt;Hash functions&lt;/h2&gt;
  &lt;p id=&quot;08Xr&quot;&gt;Now let&amp;#x27;s talk about hash functions, it&amp;#x27;s the most interesting part of hash tables. There&amp;#x27;re some bases for creating &amp;quot;right&amp;quot; hash function:&lt;/p&gt;
  &lt;ol id=&quot;kXkR&quot;&gt;
    &lt;li id=&quot;BfdA&quot;&gt;It should be efficiently computable, let&amp;#x27;s say in constant time and usually with using arithmetic operations&lt;/li&gt;
    &lt;li id=&quot;Jf8j&quot;&gt;it should produce few collisions. Collision is situation, when hash function generates the same output for different inputs. To put in simply: h(x) = h(y), even though x != y.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;0ssR&quot;&gt;Exist a lot of different hash functions.&lt;/p&gt;
  &lt;p id=&quot;oovQ&quot;&gt;Example of hash function (division hashing):&lt;/p&gt;
  &lt;pre id=&quot;wIQb&quot; data-lang=&quot;cpp&quot;&gt;const int HashTable::hash_function(const int key){        
    // distribute numbers by last value of number        
    // 101 =&amp;gt; first group; 607 =&amp;gt; seventh group        
    return key % hash_groups;    
}&lt;/pre&gt;
  &lt;p id=&quot;SVhD&quot;&gt;It satisfies first criteria of efficiency, but consecutive keys are mapped to consecutive entries, and this is does not do a good job of breaking up clusters.&lt;/p&gt;
  &lt;p id=&quot;qWt3&quot;&gt;Here are 3 more commonly used hash functions:&lt;/p&gt;
  &lt;p id=&quot;GRgq&quot;&gt;1) Multiplicative hash function:&lt;/p&gt;
  &lt;p id=&quot;3G4S&quot;&gt;&lt;strong&gt;&lt;em&gt;h(x) = (ax) mod m:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;8rfU&quot; data-lang=&quot;cpp&quot;&gt;const int HashTable::hash_function(const int key){
    int a = lower_limit + rand() % upper_limit;
    
    return (a * key) % hash_groups;
}&lt;/pre&gt;
  &lt;p id=&quot;hzYK&quot;&gt;2) Linear hash function:&lt;/p&gt;
  &lt;p id=&quot;Imx2&quot;&gt;&lt;strong&gt;h(x) = (ax + b) mod m:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;Sklh&quot; data-lang=&quot;cpp&quot;&gt;const int HashTable::hash_function(const int key){
    int a = lower_limit + rand() % upper_limit;
    int b = lower_limit + rand() % upper_limit;
    
    return (a * x + b) % hash_groups;
}&lt;/pre&gt;
  &lt;p id=&quot;Vpze&quot;&gt;3) Polynomial hash function:&lt;/p&gt;
  &lt;p id=&quot;0MMW&quot;&gt;&lt;strong&gt;&lt;em&gt;Polynomial hash function&lt;/em&gt;&lt;/strong&gt; is extend of the &lt;strong&gt;&lt;em&gt;Linear hash function. &lt;/em&gt;&lt;/strong&gt;it gives us opportunity to handle a sequences of objects, such as strings or multi-dimensional coordinates.&lt;/p&gt;
  &lt;p id=&quot;amI2&quot;&gt;&lt;strong&gt;&lt;em&gt;h(x₀, . . . , xₙ) = (∑(k-1, i=0) cᵢ(p^i)) mod m&lt;/em&gt;&lt;/strong&gt;:&lt;/p&gt;
  &lt;p id=&quot;grce&quot;&gt;A useful algorithm for computing polynomials is called Horner’s rule.&lt;/p&gt;
  &lt;pre id=&quot;TMJ4&quot; data-lang=&quot;cpp&quot;&gt;const int HashTable::hash_function(const std::string key){
    int p = lower_limit + rand() % upper_limit;
    int hash_value = 0;
    for(int i = key.length() - 1; i &amp;gt;= 0; i--){
        hash_value = (p * hash_value + static_cast&amp;lt;int&amp;gt;(key[i])) % hash_groups;
    }
    
    return hash_value;
}&lt;/pre&gt;
  &lt;h3 id=&quot;05wr&quot; data-align=&quot;center&quot;&gt;&lt;strong&gt;Universal hashing&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;fZQ7&quot;&gt;The main problem of listed hash functions, that it&amp;#x27;s easy to find elements which hash function&amp;#x27;s will have the same result. But at the same time with random elements we are able to talk about some kind of math prediction. Actually for random data it&amp;#x27;ll be working just fine, the average time of finding element&amp;#x27;ll be O(1). But the world is cruel and random data is a really rare thing. That&amp;#x27;s why hash function should be designed for each data in it&amp;#x27;s own way. Here comes the idea about &amp;quot;universal hashing&amp;quot;.&lt;/p&gt;
  &lt;p id=&quot;BaRC&quot;&gt;A family of hash functions &lt;strong&gt;&lt;em&gt;H = {hᵢ}, hᵢ: X-&amp;gt;{0,1...M-1}&lt;/em&gt;&lt;/strong&gt; is called universal if&lt;br /&gt;&lt;strong&gt;&lt;em&gt;Ɐx₁,y₁ є X, x₁ != y₁&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;em&gt;P(hᵢ(x₁) = hᵢ(y₁)) &amp;lt;= 1/M&lt;/em&gt;&lt;/strong&gt;. In words: A family of hash-functions is called universal if for two random not equal elements the probability of choosing hash-function gives collision not bigger, than 1/M. With universal hashing there can&amp;#x27;t be any type of data, which could make hash table works slow. It&amp;#x27;s just impossible because we choose hash function in a random way. &lt;/p&gt;
  &lt;p id=&quot;eRnK&quot;&gt;Let&amp;#x27;s have a look at the code for other functions.&lt;/p&gt;
  &lt;p id=&quot;yXZh&quot;&gt;Firstly, &lt;strong&gt;&lt;em&gt;insert_item. &lt;/em&gt;&lt;/strong&gt;I think there is nothing complicated about it.We iterate over list until find the right position for value variable based on&lt;strong&gt;&lt;em&gt; hash value.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;3vbP&quot; data-lang=&quot;cpp&quot;&gt;void HashTable::insert_item(const int key, const std::string value){
    //choose hash function depends on your needs 
    int hash_value = hash_function(key); 
    
    auto&amp;amp; cell = table[hash_value]; 
    auto begin_itr = std::begin(cell); 
    bool key_exists = false;
     
    for (; begin_itr != std::end(cell); begin_itr++){ 
        if (begin_itr-&amp;gt;first == key){ 
            begin_itr-&amp;gt;second = value; 
            key_exists = true; 
            std::cout &amp;lt;&amp;lt; &amp;quot;Key exists, values was replaced&amp;quot; &amp;lt;&amp;lt; std::endl; 
            break; 
         } 
     }
      
     if (!key_exists) 
         std::cout &amp;lt;&amp;lt; &amp;quot;Key was inserted&amp;quot; &amp;lt;&amp;lt; std::endl; 
         cell.emplace_back(key, value); 
}&lt;/pre&gt;
  &lt;p id=&quot;yC4k&quot;&gt;Almost the same for &lt;strong&gt;&lt;em&gt;remove_item&lt;/em&gt;&lt;/strong&gt;. Iterate over list, until find key value. &lt;/p&gt;
  &lt;pre id=&quot;Er6V&quot; data-lang=&quot;cpp&quot;&gt;void HashTable::remove_item(const int key){ 
    int hash_value = hash_function(key); 
    
    auto&amp;amp; cell = table[hash_value]; 
    auto begin_itr = std::begin(cell); 
    bool key_exists = false; 
    
    for (; begin_itr != std::end(cell); begin_itr++){ 
        if (begin_itr-&amp;gt;first == key){ 
            begin_itr = cell.erase(begin_itr); 
            key_exists = true; 
            std::cout &amp;lt;&amp;lt; &amp;quot;Key exists, values was erased&amp;quot; &amp;lt;&amp;lt; std::endl; 
            break; 
         } 
     } 
     if (!key_exists) 
         std::cout &amp;lt;&amp;lt; &amp;quot;Key doesn&amp;#x27;t exist&amp;quot; &amp;lt;&amp;lt; std::endl; 
}&lt;/pre&gt;
  &lt;p id=&quot;72a4&quot;&gt;Typical and evident &lt;strong&gt;&lt;em&gt;is_empty&lt;/em&gt;&lt;/strong&gt; function:&lt;/p&gt;
  &lt;pre id=&quot;xNGc&quot; data-lang=&quot;cpp&quot;&gt;bool HashTable::is_empty() const{ 
    int sum = 0; 
    for (int i = 0; i &amp;lt; hash_groups; i++){ 
        sum += table[i].size(); 
        if (sum &amp;gt; 0) 
            return false; 
     }
     
     return true; 
}&lt;/pre&gt;
  &lt;p id=&quot;8yBg&quot;&gt;Function&lt;strong&gt;&lt;em&gt; print&lt;/em&gt;&lt;/strong&gt; also is evident.&lt;/p&gt;
  &lt;pre id=&quot;pRcM&quot; data-lang=&quot;cpp&quot;&gt;void HashTable::print(){ 
    for (int i = 0; i &amp;lt; hash_groups; i++){ 
        if (table[i].size() == 0) 
            continue;
             
        auto begin_itr = table[i].begin(); 
        std::cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot; cell&amp;quot; &amp;lt;&amp;lt; std::endl;
         
        for (;begin_itr != table[i].end(); begin_itr++){ 
            std::cout &amp;lt;&amp;lt; &amp;quot;Key: &amp;quot; &amp;lt;&amp;lt; begin_itr-&amp;gt;first &amp;lt;&amp;lt; &amp;quot; Value: &amp;quot; &amp;lt;&amp;lt; begin_itr-&amp;gt;second &amp;lt;&amp;lt; std::endl; 
        } 
        std::cout &amp;lt;&amp;lt; &amp;quot;- - -&amp;quot; &amp;lt;&amp;lt; std::endl; 
     } 
}&lt;/pre&gt;
  &lt;p id=&quot;cNeY&quot;&gt;We did a good work for now, but hash table still doesn&amp;#x27;t have any mechanism to resolve collisions and it&amp;#x27;s going to be our next topic for the next article.&lt;/p&gt;
  &lt;p id=&quot;KITM&quot;&gt;Full code: &lt;a href=&quot;https://github.com/rastr-0/Simple_algorithms/blob/master/hash_table/HashTable.cpp&quot; target=&quot;_blank&quot;&gt;https://github.com/rastr-0/Simple_algorithms/blob/master/hash_table/HashTable.cpp&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;g2MD&quot; data-align=&quot;right&quot;&gt;see ya soon&lt;/p&gt;
  &lt;p id=&quot;fFmz&quot; data-align=&quot;right&quot;&gt;@rastr&lt;/p&gt;
  &lt;p id=&quot;LA62&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;vmdw&quot;&gt;References:&lt;/p&gt;
  &lt;ul id=&quot;jBZp&quot;&gt;
    &lt;li id=&quot;VRw5&quot;&gt;&lt;a href=&quot;https://www.cs.umd.edu/class/fall2019/cmsc420-0201/Lects/lect10-hash-basics.pdf&quot; target=&quot;_blank&quot;&gt;https://www.cs.umd.edu/class/fall2019/cmsc420-0201/Lects/lect10-hash-basics.pdf&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;ivNe&quot;&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Horner%27s_method&quot; target=&quot;_blank&quot;&gt;https://en.wikipedia.org/wiki/Horner%27s_method&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;dweY&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=1-NO9rgmM_Y&amp;t=3231s&quot; target=&quot;_blank&quot;&gt;https://www.youtube.com/watch?v=1-NO9rgmM_Y&amp;amp;t=3231s&lt;/a&gt; (ru)&lt;/li&gt;
  &lt;/ul&gt;

</content></entry><entry><id>rastr_0:text_justification</id><link rel="alternate" type="text/html" href="https://teletype.in/@rastr_0/text_justification?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=rastr_0"></link><title>Text justification</title><published>2022-12-11T18:18:09.518Z</published><updated>2022-12-11T19:02:56.105Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/1f/95/1f959dd4-d378-4b18-af7f-f46ba92db805.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/ac/db/acdb3622-26d2-44b2-a641-0db59c685942.png&quot;&gt;Hi everyone, in this article I'll try to explain how to implement text justification algorithm. We'll use python for this. Let's get started.</summary><content type="html">
  &lt;p id=&quot;Jv7h&quot;&gt;Hi everyone, in this article I&amp;#x27;ll try to explain how to implement text justification algorithm. We&amp;#x27;ll use python for this. Let&amp;#x27;s get started.&lt;/p&gt;
  &lt;p id=&quot;ZAiv&quot;&gt;I saw this task at codewars a few month ago and solved it. The task formulates in the following way: &amp;quot;task is to emulate text justification in monospace font. You will be given a single-lined text and the expected justification width&amp;quot;.&lt;/p&gt;
  &lt;p id=&quot;515W&quot;&gt;Here are the rules:&lt;/p&gt;
  &lt;ul id=&quot;P6nQ&quot;&gt;
    &lt;li id=&quot;f6IX&quot;&gt;Use spaces to fill in the gaps between words.&lt;/li&gt;
    &lt;li id=&quot;Q86k&quot;&gt;Each line should contain as many words as possible.&lt;/li&gt;
    &lt;li id=&quot;8qK9&quot;&gt;Use &amp;#x27;\n&amp;#x27; to separate lines.&lt;/li&gt;
    &lt;li id=&quot;glMz&quot;&gt;Gap between words can&amp;#x27;t differ by more than one space.&lt;/li&gt;
    &lt;li id=&quot;ykvk&quot;&gt;Lines should end with a word not a space.&lt;/li&gt;
    &lt;li id=&quot;LAB0&quot;&gt;&amp;#x27;\n&amp;#x27; is not included in the length of a line.&lt;/li&gt;
    &lt;li id=&quot;9Up3&quot;&gt;Large gaps go first, then smaller ones (&amp;#x27;Lorem--ipsum--dolor--sit-amet,&amp;#x27; (2, 2, 2, 1 spaces)).&lt;/li&gt;
    &lt;li id=&quot;6hdi&quot;&gt;Last line should not be justified, use only one space between words.&lt;/li&gt;
    &lt;li id=&quot;ySdj&quot;&gt;Last line should not contain &amp;#x27;\n&amp;#x27;&lt;/li&gt;
    &lt;li id=&quot;HrVg&quot;&gt;Strings with one word do not need gaps (&amp;#x27;somelongword\n&amp;#x27;).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;3P8R&quot;&gt;So, the result of justified text should look like this:&lt;/p&gt;
  &lt;figure id=&quot;yN8E&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ac/db/acdb3622-26d2-44b2-a641-0db59c685942.png&quot; width=&quot;1002&quot; /&gt;
    &lt;figcaption&gt;Example of justifed text&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;TtFS&quot;&gt;The idea of implementation of the algorithm is described in following text. &lt;/p&gt;
  &lt;p id=&quot;H5Y6&quot;&gt;While we can add words to line we are doing it, if next word + current line length is bigger, than width, we don&amp;#x27;t add this word to the current line. If current line width still less, than width, we add spaces to line in the direction from left to right. &lt;/p&gt;
  &lt;pre id=&quot;gflP&quot; data-lang=&quot;python&quot;&gt;def justify(text, width):
    # starting variables
    line = &amp;#x27;&amp;#x27;
    linelength = 0
    finished_text = &amp;#x27;&amp;#x27;
    # iterate over text, item represents each word
    for item in text.split():
        # check if current line + new word is bigger than given width
        if linelength + len(item) &amp;gt; width:
            # delete space after last word
            line = line[:-1]
            linelength -= 1
            # if length of line is less than width, then add spaces to this line
            if width - linelength &amp;gt; 0:
                line = add_spaces(line, width - linelength)
            # add line with all needed spaces to the final text version
            finished_text += line + &amp;#x27;\n&amp;#x27;
            # setup variables to starting positions
            line = &amp;#x27;&amp;#x27;
            linelength = 0
        # if current line + new_word is less than width, then add new_word to current line
        else:
            linelength += len(item)
            line += item
            linelength += 1
            line += &amp;#x27; &amp;#x27;
    # delete last space because of conditions on Codewars
    line = line[:-1]
    finished_text += line
    
    return finished_text
    &lt;/pre&gt;
  &lt;p id=&quot;t2aX&quot;&gt;Let&amp;#x27;s see on the code in order. It&amp;#x27;s starting from initializing starting variables. Further, I start to iterate over string and face main condition.&lt;/p&gt;
  &lt;pre id=&quot;occI&quot; data-lang=&quot;python&quot;&gt;if linelength + len(item) &amp;gt; width:&lt;/pre&gt;
  &lt;p id=&quot;ErSb&quot;&gt;It&amp;#x27;s really important to have &lt;strong&gt;&lt;em&gt;&amp;gt;&lt;/em&gt;&lt;/strong&gt; sign and not &lt;strong&gt;&lt;em&gt;&amp;gt;=,&lt;/em&gt;&lt;/strong&gt; because anyway line width will be (width + 1) size.&lt;/p&gt;
  &lt;p id=&quot;HvDc&quot;&gt;Next nested condtion is about adding additional spaces to line. &lt;/p&gt;
  &lt;pre id=&quot;z5Lk&quot; data-lang=&quot;python&quot;&gt;if width - linelength &amp;gt; 0:
    line = add_spaces(line, width - linelength)&lt;/pre&gt;
  &lt;p id=&quot;1tzF&quot;&gt;The realization of &lt;strong&gt;&lt;em&gt;add_spaces&lt;/em&gt;&lt;/strong&gt; function will be below.  &lt;/p&gt;
  &lt;p id=&quot;OYV5&quot;&gt;If line width + word is less than width we don&amp;#x27;t do anything special, just adding word to line and one space after it.&lt;/p&gt;
  &lt;p id=&quot;6Ra9&quot;&gt;Now let&amp;#x27;s dive into&lt;strong&gt;&lt;em&gt; add_spaces&lt;/em&gt;&lt;/strong&gt; function.&lt;/p&gt;
  &lt;p id=&quot;U8zj&quot;&gt;The idea of this function is next: Count needed amount of additional spaces, iterate over line (from the left to the right side) and put additional spaces between words, also decrease variable with needed amount of spaces. If after one circle there is still not enough spaces -&amp;gt; repeat it. &lt;/p&gt;
  &lt;pre id=&quot;V6P5&quot; data-lang=&quot;python&quot;&gt;def add_spaces(line, count_spaces):
    i = 0
    splitted_line = line.split()
    total_words = sum(1 for _ in splitted_line)
    if total_words == 1:
        return line
    # start iterate over list if there are more than one word
    while True:
        # if it&amp;#x27;s last word and it&amp;#x27;s line still needed more spaces then iterate over list from the start (i = 0)
        if count_spaces != 0 and i == (total_words - 1):
            i = 0
        # check if it&amp;#x27;s still needed to add spaces to line
        if count_spaces &amp;gt; 0:
            splitted_line[i] += &amp;#x27; &amp;#x27;
            count_spaces -= 1
            i += 1
        else:
            break
    return &amp;#x27; &amp;#x27;.join(splitted_line)&lt;/pre&gt;
  &lt;p id=&quot;22zA&quot;&gt;Firstly, count amount of words in given line. Then, based on amount of words, add spaces to the line.&lt;/p&gt;
  &lt;pre id=&quot;22zA&quot; data-lang=&quot;python&quot;&gt;if count_spaces != 0 and i == (total_words - 1):&lt;/pre&gt;
  &lt;p id=&quot;1nQl&quot;&gt;This condition detects, if already has been made one iteration over list but we still got spaces to add.&lt;/p&gt;
  &lt;p id=&quot;Euln&quot;&gt;As always full code can be found at my GitHub: &lt;a href=&quot;https://github.com/rastr-0/teletype_source_files/tree/main/text_justification&quot; target=&quot;_blank&quot;&gt;https://github.com/rastr-0/teletype_source_files/tree/main/text_justification&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;4XJm&quot; data-align=&quot;right&quot;&gt;See ya soon&lt;/p&gt;
  &lt;p id=&quot;dyY4&quot; data-align=&quot;right&quot;&gt;@rastr&lt;/p&gt;

</content></entry><entry><id>rastr_0:RSA_part_2</id><link rel="alternate" type="text/html" href="https://teletype.in/@rastr_0/RSA_part_2?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=rastr_0"></link><title>RSA, part 2: encryption and decryption</title><published>2022-08-27T17:47:11.306Z</published><updated>2022-08-27T17:47:11.306Z</updated><summary type="html">Hi there! It's second part about RSA alorithm. We'll talk about encryption of messages and their decryption. For encyption and decryption we use the same operation: modular exponention. So, basically what we need to do is to create pow_mod function. We can implement it with 2 different approaches: recursion and iterative realizations. </summary><content type="html">
  &lt;p id=&quot;sDgB&quot;&gt;Hi there! It&amp;#x27;s second part about RSA alorithm. We&amp;#x27;ll talk about encryption of messages and their decryption. For encyption and decryption we use the same operation: modular exponention. So, basically what we need to do is to create &lt;em&gt;pow_mod&lt;/em&gt; function. We can implement it with 2 different approaches: recursion and iterative realizations. &lt;/p&gt;
  &lt;p id=&quot;wrdP&quot;&gt;But firstly we need to define some conditions. Let&amp;#x27;s define &lt;strong&gt;&lt;em&gt;f&lt;/em&gt;&lt;/strong&gt; function. It should get &lt;em&gt;&lt;strong&gt;x&lt;/strong&gt;&lt;/em&gt;^&lt;strong&gt;&lt;em&gt;y&lt;/em&gt;&lt;/strong&gt; mod &lt;em&gt;&lt;strong&gt;n&lt;/strong&gt;&lt;/em&gt; values and &lt;strong&gt;&lt;em&gt;result &lt;/em&gt;&lt;/strong&gt;value.&lt;/p&gt;
  &lt;ol id=&quot;84Ut&quot;&gt;
    &lt;li id=&quot;U8li&quot;&gt;if &lt;strong&gt;&lt;em&gt;y&lt;/em&gt;&lt;/strong&gt; = 0, then return &lt;strong&gt;&lt;em&gt;result&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
    &lt;li id=&quot;5FhN&quot;&gt;if the smallest bit of &lt;strong&gt;&lt;em&gt;y&lt;/em&gt;&lt;/strong&gt; is 0 (&lt;em&gt;&lt;strong&gt;y&lt;/strong&gt;&lt;/em&gt; is even number) , then f(&lt;strong&gt;&lt;em&gt;x&lt;/em&gt;&lt;/strong&gt;^2 mod &lt;strong&gt;&lt;em&gt;n&lt;/em&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;em&gt;y&lt;/em&gt;&lt;/strong&gt; &amp;gt;&amp;gt; 1, &lt;em&gt;&lt;strong&gt;n&lt;/strong&gt;&lt;/em&gt;, &lt;strong&gt;&lt;em&gt;result&lt;/em&gt;&lt;/strong&gt;)&lt;/li&gt;
    &lt;li id=&quot;yOBN&quot;&gt;if the smallest bit of &lt;em&gt;&lt;strong&gt;y&lt;/strong&gt;&lt;/em&gt; is 1 (&lt;strong&gt;&lt;em&gt;y&lt;/em&gt;&lt;/strong&gt; is odd number), then f(&lt;em&gt;&lt;strong&gt;x&lt;/strong&gt;&lt;/em&gt;^2 mod &lt;strong&gt;&lt;em&gt;n&lt;/em&gt;&lt;/strong&gt;, &lt;em&gt;&lt;strong&gt;y&lt;/strong&gt;&lt;/em&gt; &amp;gt;&amp;gt; 1, &lt;strong&gt;&lt;em&gt;n&lt;/em&gt;&lt;/strong&gt;, &lt;em&gt;&lt;strong&gt;result&lt;/strong&gt;&lt;/em&gt; * &lt;strong&gt;&lt;em&gt;x&lt;/em&gt;&lt;/strong&gt; mod &lt;em&gt;&lt;strong&gt;n&lt;/strong&gt;&lt;/em&gt;)&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;0wQ9&quot;&gt;That&amp;#x27;s all, simple and smart.&lt;/p&gt;
  &lt;h3 id=&quot;YuZd&quot; data-align=&quot;center&quot;&gt;Implementation&lt;/h3&gt;
  &lt;p id=&quot;RptZ&quot;&gt; Let&amp;#x27;s try to implement it. First will be implementation with recursion.&lt;/p&gt;
  &lt;pre id=&quot;cIKF&quot; data-lang=&quot;cpp&quot;&gt;long f(long x, long y, long n, long res){ 
    if (y == 0) 
        return res; 
    // if the smallest (last from right side) bit is 1, if so, then number is odd 
    else if (y &amp;amp; 0x01) 
        return f((x * x) % n, y &amp;gt;&amp;gt; 1, n, (res * x) % n); 
    // if the smallest (last from right side) bit is 0, then number is even 
    return f((x * x) % n, y &amp;gt;&amp;gt; 1, n, res);
} 
long pow_mod(long x, long y, long n){ 
    return f(x, y, n, 1);
}&lt;/pre&gt;
  &lt;p id=&quot;x3Np&quot;&gt;Now some explanations, why I check if number is even or odd (&lt;strong&gt;&lt;em&gt;y &amp;amp; 0x01 &lt;/em&gt;&lt;/strong&gt;or&lt;strong&gt;&lt;em&gt; y &amp;amp; 1 &lt;/em&gt;&lt;/strong&gt;or&lt;strong&gt;&lt;em&gt; y &amp;amp; 0x1&lt;/em&gt;&lt;/strong&gt;) in this unclear way. It&amp;#x27;s just simply faster to use bit operations. Why it still works right? If we represent number in binary view, then we&amp;#x27;ll get interesting refularity: each even&amp;#x27;s number smallest bit is always 0 and each odd&amp;#x27;s number smallest bit is always 1. If you have time, you can convert any number to binary view and check. The same idea with using &lt;strong&gt;&lt;em&gt;y &amp;gt;&amp;gt; 1&lt;/em&gt;&lt;/strong&gt; instead of &lt;strong&gt;&lt;em&gt;y / 2&lt;/em&gt;&lt;/strong&gt;. It works faster because it&amp;#x27;s a bit operation and bit operations always work fast. &lt;/p&gt;
  &lt;p id=&quot;jt5s&quot;&gt;Now iterative realization. It&amp;#x27;s better to use this implementation because you won&amp;#x27;t have any problems with call stack which of course has limits.&lt;/p&gt;
  &lt;pre id=&quot;0nzD&quot; data-lang=&quot;cpp&quot;&gt;long pow_mod(long x, long y, long n){ 
    long res = 1; 
    // while y != 0 
    while (y){ 
        // if the smallest bit is 1 then number is odd 
        if (y &amp;amp; 0x01) 
            res = (res * x) % n; 
        x = (x * x) % n; 
        y &amp;gt;&amp;gt;= 1; 
    } 
    return res;
}&lt;/pre&gt;
  &lt;h3 id=&quot;cbAX&quot; data-align=&quot;center&quot;&gt;Time complexety, auxiliary space&lt;/h3&gt;
  &lt;ul id=&quot;7NIk&quot;&gt;
    &lt;li id=&quot;bXuj&quot;&gt;Implementation with recursion: O(log n), O(log n)&lt;/li&gt;
    &lt;li id=&quot;ERLd&quot;&gt;Iterative iImplementation: O(log n), O(1) - constant time&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;GZFS&quot; data-align=&quot;center&quot;&gt;Encryption and decryption&lt;/h3&gt;
  &lt;p id=&quot;SocP&quot;&gt;For encryption data we&amp;#x27;ll use this formula: &lt;strong&gt;&lt;em&gt;m^e mod n&lt;/em&gt;&lt;/strong&gt;. For decription data we&amp;#x27;ll use &lt;strong&gt;&lt;em&gt;c^d mod n&lt;/em&gt;&lt;/strong&gt; formula. &lt;/p&gt;
  &lt;pre id=&quot;mna9&quot; data-lang=&quot;cpp&quot;&gt;// encrypted text (c) = m^e mod n 
long long c = pow_mod(m, e, n); 
std::cout &amp;lt;&amp;lt; &amp;quot;encrypted text: &amp;quot; &amp;lt;&amp;lt; c &amp;lt;&amp;lt; std::endl; 0
// decrypted text (m) = c^d mod n 
m = pow_mod(c, d, n); 
std::cout &amp;lt;&amp;lt; &amp;quot;decrypted text: &amp;quot; &amp;lt;&amp;lt; m;&lt;/pre&gt;
  &lt;p id=&quot;Kifd&quot;&gt;Full code: &lt;a href=&quot;https://github.com/rastr-0/Simple_algorithms/blob/master/RSA/rsa.cpp&quot; target=&quot;_blank&quot;&gt;https://github.com/rastr-0/Simple_algorithms/blob/master/RSA/rsa.cpp&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;flQD&quot; data-align=&quot;right&quot;&gt;see ya soon&lt;/p&gt;
  &lt;p id=&quot;kQiO&quot; data-align=&quot;right&quot;&gt;@rastr&lt;/p&gt;

</content></entry><entry><id>rastr_0:RSA_part_1</id><link rel="alternate" type="text/html" href="https://teletype.in/@rastr_0/RSA_part_1?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=rastr_0"></link><title>RSA, part 1: generating private and public keys</title><published>2022-08-12T23:37:00.912Z</published><updated>2022-08-12T23:37:00.912Z</updated><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/32/45/32455594-c4cf-47fa-83cf-0c9a036a9d44.jpeg&quot;&gt;Hi there. It's first part about RSA algorithm with using c++, I'll provide information and code about generating public and private keys. Let's get started. RSA is public key cryptosystem which widely used for transfering data. It was descovered in 1977 by Ron Rivest, Adi Shamir and Leonard Adleman. RSA creates public key with using two large prime numbers and auxiliary value. The idea of all public key cryptosystems is simple:</summary><content type="html">
  &lt;p id=&quot;0cgr&quot;&gt;Hi there. It&amp;#x27;s first part about RSA algorithm with using c++, I&amp;#x27;ll provide information and code about generating public and private keys. Let&amp;#x27;s get started. RSA is public key cryptosystem which widely used for transfering data. It was descovered in 1977 by Ron Rivest, Adi Shamir and Leonard Adleman. RSA creates public key with using two large prime numbers and auxiliary value. The idea of all public key cryptosystems is simple:&lt;/p&gt;
  &lt;p id=&quot;wToE&quot;&gt;If we know &lt;strong&gt;&lt;em&gt;x&lt;/em&gt;&lt;/strong&gt;, then to calculate &lt;strong&gt;&lt;em&gt;f(x)&lt;/em&gt;&lt;/strong&gt; must be easy, if we know &lt;em&gt;&lt;strong&gt;f(x)&lt;/strong&gt;&lt;/em&gt;, then calculate &lt;strong&gt;&lt;em&gt;x&lt;/em&gt;&lt;/strong&gt; must be really hard(no effecient way to do this). Similar property has modular exponentiation.&lt;/p&gt;
  &lt;figure id=&quot;qkMp&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/32/45/32455594-c4cf-47fa-83cf-0c9a036a9d44.jpeg&quot; width=&quot;1280&quot; /&gt;
    &lt;figcaption&gt;Modular exponentiation&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;2iCC&quot;&gt;We&amp;#x27;ve got &lt;strong&gt;&lt;em&gt;c&lt;/em&gt;&lt;/strong&gt;, &lt;em&gt;&lt;strong&gt;m&lt;/strong&gt;&lt;/em&gt;, &lt;strong&gt;&lt;em&gt;e&lt;/em&gt;&lt;/strong&gt;, &lt;em&gt;&lt;strong&gt;n&lt;/strong&gt;&lt;/em&gt; and &lt;strong&gt;&lt;em&gt;d&lt;/em&gt;&lt;/strong&gt; values. Let&amp;#x27;s take a look on first expression. We&amp;#x27;ve got &lt;em&gt;&lt;strong&gt;c&lt;/strong&gt;&lt;/em&gt;, &lt;strong&gt;&lt;em&gt;m&lt;/em&gt;&lt;/strong&gt;, &lt;em&gt;&lt;strong&gt;e&lt;/strong&gt;&lt;/em&gt; and &lt;strong&gt;&lt;em&gt;n&lt;/em&gt;&lt;/strong&gt; values: &lt;strong&gt;&lt;em&gt;m&lt;/em&gt;&lt;/strong&gt; stands for text which we want to encrypt, &lt;em&gt;&lt;strong&gt;c&lt;/strong&gt;&lt;/em&gt; stands for decrtypted text. It&amp;#x27;s obvious that &lt;strong&gt;&lt;em&gt;c&lt;/em&gt;&lt;/strong&gt; depends on values &lt;strong&gt;&lt;em&gt;e&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;n&lt;/em&gt;&lt;/strong&gt;. So, (&lt;strong&gt;&lt;em&gt;e&lt;/em&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;em&gt;n&lt;/em&gt;&lt;/strong&gt;) pair is public key. &lt;/p&gt;
  &lt;p id=&quot;naUW&quot;&gt;Take a look on second expression. We&amp;#x27;ve got new value &lt;em&gt;&lt;strong&gt;d&lt;/strong&gt;&lt;/em&gt;: &lt;strong&gt;&lt;em&gt;d&lt;/em&gt;&lt;/strong&gt; is value with using wich we got &lt;strong&gt;&lt;em&gt;m&lt;/em&gt;&lt;/strong&gt;(decrypted text). So, (&lt;strong&gt;&lt;em&gt;e&lt;/em&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;em&gt;d&lt;/em&gt;&lt;/strong&gt;) pair is private key.&lt;/p&gt;
  &lt;p id=&quot;LrPT&quot;&gt;Prime values kept in secret. Any message can be encrypted with using public key, but can be decrypted by someone who knows private key. For now is no efficient way to decrypte message without knowing a private key.&lt;/p&gt;
  &lt;h3 id=&quot;sUCf&quot; data-align=&quot;center&quot;&gt;Operation&lt;/h3&gt;
  &lt;p id=&quot;ilXA&quot;&gt;RSA algorithm involves 4 steps: generation, distribution, encryption and decryption. &lt;/p&gt;
  &lt;h3 id=&quot;jKLX&quot; data-align=&quot;center&quot;&gt;Key generation&lt;/h3&gt;
  &lt;p id=&quot;m01Z&quot;&gt;Here it&amp;#x27;s necessary to make a reservation about my implementation. It&amp;#x27;s quite obvious that numbers better be big, it&amp;#x27;s popular to use 1024 bit length, for this need to use libraries for big numbers (such as GMP for c++). I don&amp;#x27;t use it. Later maybe I&amp;#x27;ll post article about RSA code with using GMP library. &lt;/p&gt;
  &lt;p id=&quot;dPZw&quot;&gt;Now let&amp;#x27;s be more specific about generating values and all details. &lt;/p&gt;
  &lt;p id=&quot;pec7&quot;&gt;1. Choose 2 distinct prime numbers &lt;strong&gt;&lt;em&gt;p&lt;/em&gt;&lt;/strong&gt; and &lt;em&gt;&lt;strong&gt;q&lt;/strong&gt;&lt;/em&gt; in a random way. What we do is just generate 2 random numbers and chech if they&amp;#x27;re prime, if not - generate again. if you got any questions about &lt;strong&gt;&lt;em&gt;is_prime&lt;/em&gt;&lt;/strong&gt; function then visit &lt;a href=&quot;https://stackoverflow.com/questions/4424374/determining-if-a-number-is-prime&quot; target=&quot;_blank&quot;&gt;this topic&lt;/a&gt; on StackOverFlow. &lt;/p&gt;
  &lt;pre id=&quot;IUpl&quot; data-lang=&quot;cpp&quot;&gt;// should be compiled with c++17
#include &amp;lt;ctime&amp;gt;
#include &amp;lt;iostream&amp;gt;

#define u unsigned

// primarity test for numbers
bool is_prime(u int num){
    if (num != 2){
        if (num &amp;lt; 2 || num % 2 == 0) 
            return false; 
        for (int i = 3; i * i &amp;lt;= num; i += 2){ 
            if (num % i == 0) 
                return false; 
        }
    }
    return true; 
} &lt;/pre&gt;
  &lt;pre id=&quot;jR1B&quot; data-lang=&quot;cpp&quot;&gt;std::pair&amp;lt;int, int&amp;gt; generate_prime_numbers(u int low_lim, u int upper_lim){ 
    // u means unsigned, I defined this above
    u int first_num = 0; 
    u int second_num = 0; 
    do { 
        first_num = low_lim + (rand() % upper_lim); 
        second_num = low_lim + (rand() % upper_lim);  
    } while (!is_prime(first_num) || !is_prime(second_num)); 
     
    return std::make_pair(first_num, second_num); 
} &lt;/pre&gt;
  &lt;p id=&quot;buH3&quot;&gt;2. Compute &lt;strong&gt;&lt;em&gt;n&lt;/em&gt;&lt;/strong&gt; = &lt;strong&gt;&lt;em&gt;p&lt;/em&gt;&lt;/strong&gt; * &lt;strong&gt;&lt;em&gt;q&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;QoVU&quot; data-lang=&quot;cpp&quot;&gt;// I use long long type because n probably is a big number 
long long n = p * q;&lt;/pre&gt;
  &lt;p id=&quot;fH8C&quot;&gt;3. Calculate Euler&amp;#x27;s phi function(Euler&amp;#x27;s totient function). Function counts positive integers that a &lt;a href=&quot;https://en.wikipedia.org/wiki/Coprime_integers&quot; target=&quot;_blank&quot;&gt;relatively prime&lt;/a&gt; to given &lt;em&gt;&lt;strong&gt;n&lt;/strong&gt;. &lt;/em&gt;Other words, this function counts numbers with gcd(great common devider, НОД рус.) 1 with &lt;strong&gt;&lt;em&gt;n&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
  &lt;p id=&quot;MBMx&quot;&gt;Why &lt;strong&gt;&lt;em&gt;n&lt;/em&gt;&lt;/strong&gt; has beed choosen exactly like this. We can get private &lt;strong&gt;&lt;em&gt;d&lt;/em&gt;&lt;/strong&gt; value with public &lt;strong&gt;&lt;em&gt;e&lt;/em&gt;&lt;/strong&gt; value. With &lt;strong&gt;&lt;em&gt;p&lt;/em&gt;&lt;/strong&gt; and &lt;em&gt;&lt;strong&gt;q&lt;/strong&gt;&lt;/em&gt; values is not a problem to calculate &lt;strong&gt;&lt;em&gt;phi&lt;/em&gt;&lt;/strong&gt; function, but in public key is &lt;strong&gt;&lt;em&gt;n&lt;/em&gt;&lt;/strong&gt; value. So, if we want to calculate &lt;strong&gt;&lt;em&gt;phi(n)&lt;/em&gt;&lt;/strong&gt; we need to solve factorization problem(there is no effecient way to do this).&lt;/p&gt;
  &lt;p id=&quot;mUkH&quot;&gt;4. Find &lt;strong&gt;&lt;em&gt;e&lt;/em&gt;&lt;/strong&gt; value: &lt;strong&gt;&lt;em&gt;e&lt;/em&gt;&lt;/strong&gt; value have to comply these conditions.&lt;/p&gt;
  &lt;figure id=&quot;TWkO&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/9c/b9/9cb92e77-7f0c-47ca-8fd3-324e0ebf7a13.jpeg&quot; width=&quot;1280&quot; /&gt;
    &lt;figcaption&gt;Conditions for e value&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;pre id=&quot;0bXr&quot; data-lang=&quot;cpp&quot;&gt;u int find_coprime(u int phi_res){ 
    u int e = 2; 
    while (e &amp;lt; phi_res){ 
        u int gcd_res = gcd(e, phi_res); 
        if (gcd_res == 1) 
            return e; 
        e++; 
    }     
    return e; 
} &lt;/pre&gt;
  &lt;p id=&quot;553n&quot;&gt;5. Find &lt;strong&gt;&lt;em&gt;d&lt;/em&gt;&lt;/strong&gt; value&lt;/p&gt;
  &lt;figure id=&quot;LAy8&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ab/0b/ab0b0d41-a4aa-4f71-9329-0b8305f98397.jpeg&quot; width=&quot;4392&quot; /&gt;
    &lt;figcaption&gt;Conditions for d value&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;pre id=&quot;VOcc&quot; data-lang=&quot;cpp&quot;&gt;u int calculate_d(u int phi_res, u int e){ 
    u int k = 1; 
    u int d = 0; 
     
    while ((((k * phi_res) + 1) % e) != 0) 
        k++; 
    d = ((k * phi_res) + 1) / e; 
     
    return d; 
} &lt;/pre&gt;
  &lt;p id=&quot;FJjZ&quot;&gt;Main function&lt;/p&gt;
  &lt;pre id=&quot;3h9Y&quot; data-lang=&quot;cpp&quot;&gt;int main(){ 
    srand(time(0)); 
    // from 1k to 10k 
    auto [p, q] = generate_prime_numbers(1000, 10000); 
    long long n = p * q; 
    u int phi_res = phi(p, q); 
    u int e = find_coprime(phi_res); 
    u int d = calculate_d(phi_res, e); 
     
    std::cout &amp;lt;&amp;lt; &amp;quot;(&amp;quot; &amp;lt;&amp;lt; e &amp;lt;&amp;lt; &amp;quot;, &amp;quot; &amp;lt;&amp;lt; n &amp;lt;&amp;lt; &amp;quot;) — public key&amp;quot; &amp;lt;&amp;lt; std::endl; 
    std::cout &amp;lt;&amp;lt; &amp;quot;(&amp;quot; &amp;lt;&amp;lt; e &amp;lt;&amp;lt; &amp;quot;, &amp;quot; &amp;lt;&amp;lt; d &amp;lt;&amp;lt; &amp;quot;) — private key&amp;quot;; 
    /* 
    (e, n) pair stands for public key, could be published anywhere 
    (e, d) pair stands for private key and keeps in secret 
    */ 
     
    return 0; 
}&lt;/pre&gt;
  &lt;p id=&quot;uGyT&quot;&gt;Next article&amp;#x27;ll defenitely be 2 part about RSA. &lt;/p&gt;
  &lt;p id=&quot;0238&quot;&gt;Full code on GitHub: &lt;a href=&quot;https://github.com/rastr-0/teletype_source_files/tree/main/rsa_generating_keys&quot; target=&quot;_blank&quot;&gt;https://github.com/rastr-0/teletype_source_files/tree/main/rsa_generating_keys&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;VNUW&quot; data-align=&quot;right&quot;&gt;See ya soon &lt;/p&gt;
  &lt;p id=&quot;5Mi6&quot; data-align=&quot;right&quot;&gt;@rastr&lt;/p&gt;

</content></entry><entry><id>rastr_0:solar_system</id><link rel="alternate" type="text/html" href="https://teletype.in/@rastr_0/solar_system?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=rastr_0"></link><title>2D simulation of Solar system</title><published>2022-08-04T22:02:04.192Z</published><updated>2022-08-04T22:02:04.192Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/a9/94/a994389b-6bc2-43f5-a1b2-5c87bd128c8d.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img2.teletype.in/files/9b/c8/9bc8f927-a178-469a-a7ee-b27fd42c3273.png&quot;&gt;In this article we'll try to create 2D simulation of Solar system with python and pygame lib. I consider people that are reading it are familiar with pygame lib, just basics. Let's get started. </summary><content type="html">
  &lt;p id=&quot;HDCB&quot;&gt;In this article we&amp;#x27;ll try to create 2D simulation of Solar system with python and pygame lib. I consider people that are reading it are familiar with pygame lib, just basics. Let&amp;#x27;s get started. &lt;/p&gt;
  &lt;p id=&quot;ryJW&quot;&gt;That&amp;#x27;s how looks framework of pygame app.&lt;/p&gt;
  &lt;pre id=&quot;5P0f&quot; data-lang=&quot;python&quot;&gt;import pygame
import math

# colors in rgb type for drawing planets and Sun
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
BLUE = (26, 209, 255)
RED = (255, 92, 51)
GREY = (80, 71, 81)
ORANGE = (204, 163, 0)

pygame.init()
WIDTH, HEIGHT = 800, 800
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(&amp;quot;Solar system simulation&amp;quot;)
def main():
    run = True
    clock = pygame.time.Clock()
    
    while run:
        # set up 60 fps
        clock.tick(60)
        WIN.fill(BLACK)
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
    pygame.quit()

    
main()&lt;/pre&gt;
  &lt;p id=&quot;Zfk7&quot;&gt;If you start it, you&amp;#x27;ll see black sreen and working button for closing window.&lt;/p&gt;
  &lt;p id=&quot;ax1E&quot;&gt;Now let&amp;#x27;s define &lt;em&gt;&lt;strong&gt;Planet class&lt;/strong&gt;&lt;/em&gt;. It&amp;#x27;s also easy to change SCALE in simulation, just increase first number and check it out. &lt;/p&gt;
  &lt;pre id=&quot;uJPN&quot; data-lang=&quot;python&quot;&gt;class Planet: 
    # astronomical unit, distance from the Sun to the Earth in meters 
    AU = 149.6e6 * 1000 
    G = 6.67428e-11 
    SCALE = 80 / AU # 1 AU = 100 pixels 
    TIMESTEP = 3600 * 24 # 1 day (3600 seconds = 1 hour)
    &lt;/pre&gt;
  &lt;p id=&quot;YYD0&quot;&gt;Here is initializing function of Planet class, nothing complicated but I&amp;#x27;d like to note I use sun variable to identify Sun. Technically sun isn&amp;#x27;t a planet, it&amp;#x27;s star but who cares? :) So, all planets have False value and only Sun has True. &lt;/p&gt;
  &lt;pre id=&quot;uJPN&quot; data-lang=&quot;python&quot;&gt;def __init__(self, x, y, radius, color, mass): 
    self.x = x 
    self.y = y 
    self.radius = radius 
    self.color = color 
    self.mass = mass  
    self.sun = False 
    self.distance_to_sun = 0 
    self.orbit = []  
    self.x_velocity = 0 
    self.y_velocity = 0&lt;/pre&gt;
  &lt;p id=&quot;3rf5&quot;&gt;For now let&amp;#x27;s create &lt;em&gt;&lt;strong&gt;draw&lt;/strong&gt;&lt;/em&gt; function basement.&lt;/p&gt;
  &lt;pre id=&quot;rcn0&quot; data-lang=&quot;python&quot;&gt;def draw(self, win): 
    # WIDTH / 2 and HEIGHT / 2 give a chance to draw in the middle of the scren
    # in Pygame center of the screen is at the top left corner
    x = self.x * self.SCALE + WIDTH / 2 
    y = self.y * self.SCALE + HEIGHT / 2
    # draw circle with set color and radius in the middle of the screen 
    pygame.draw.circle(win, self.color, (x, y), self.radius)&lt;/pre&gt;
  &lt;p id=&quot;m6pI&quot;&gt;Now we&amp;#x27;ll add Sun and other planets to the simulation and check if &lt;strong&gt;&lt;em&gt;draw&lt;/em&gt;&lt;/strong&gt; function works right. Code below should be added in the main function before while cycle. The reason why I put - in first value for Earth and Mars it&amp;#x27;s because I want to see planets in different sides(left or right). &lt;/p&gt;
  &lt;p id=&quot;B57X&quot;&gt;By the way, why this project is calling simulation because I use real numbers to simulate movements of planets with gravity. All numbers easy to google and check. &lt;/p&gt;
  &lt;pre id=&quot;YXUE&quot; data-lang=&quot;python&quot;&gt;sun = Planet(0, 0, 15, YELLOW, 1.98892 * 10**30) 
sun.sun = True
# further it&amp;#x27;s easy to add more planets
mercury = Planet(0.387 * Planet.AU, 0, 4, GREY, 0.330 * 10**23)
venus = Planet(0.723 * Planet.AU, 0, 7, WHITE, 4.8685 * 10**24)
earth = Planet(-1 * Planet.AU, 0, 8, BLUE, 5.9742 * 10**24)
mars = Planet(-1.524 * Planet.AU, 0, 6, RED, 6.39 * 10**23)

planets = [sun, mercury, venus, earth, mars]

def main():
    run = True
    clock = pygame.time.Clock()
    
    while run:
        # set up 60 fps
        clock.tick(60)
        WIN.fill(BLACK)
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
        for planet in planets:
            planet.draw(WIN)
        pygame.display.update()
    pygame.quit()

    
main()&lt;/pre&gt;
  &lt;p id=&quot;mBfL&quot;&gt;That&amp;#x27;s what we got. Planets with actual distances reduced in many times&lt;/p&gt;
  &lt;figure id=&quot;y5h1&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/9b/c8/9bc8f927-a178-469a-a7ee-b27fd42c3273.png&quot; width=&quot;979&quot; /&gt;
    &lt;figcaption&gt;Planets of Solar system &lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;TpZ7&quot;&gt;Now I want to disscus the hardest part of article - realisation of gravity. We need to calculate distance beetwen two points and force that acts on two objects and farther with using cos and sin calculate Fy and Fx movement. &lt;/p&gt;
  &lt;figure id=&quot;tvkv&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/06/c9/06c9200c-4821-43cc-859f-292e7b53bdd1.png&quot; width=&quot;884&quot; /&gt;
    &lt;figcaption&gt;Formula illustration&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;pre id=&quot;rHzn&quot; data-lang=&quot;python&quot;&gt;def attraction(self, other):
    # calculating R(distance between 2 points) 
    other_x, other_y = other.x, other.y 
    distance_x = other_x - self.x 
    distance_y = other_y - self.y 
    distance = math.sqrt(distance_x ** 2 + distance_y ** 2)  
    if other.sun: 
        self.distance_to_sun = distance
    # calculating force_x and force_y to define how to move object    
    force = self.G * self.mass * other.mass / distance ** 2 
    angle = math.atan2(distance_y, distance_x) 
    force_x = math.cos(angle) * force 
    force_y = math.sin(angle) * force  
    
    return force_x, force_y&lt;/pre&gt;
  &lt;p id=&quot;fghB&quot;&gt;Next step is setup start y velocity for planets in &lt;strong&gt;&lt;em&gt;main&lt;/em&gt;&lt;/strong&gt; function and add new if your sreen is quite big for this :) Again minus before number determines direction of movement(clockwise or counterclockwise).&lt;/p&gt;
  &lt;pre id=&quot;6tAt&quot; data-lang=&quot;python&quot;&gt;# start y velocity
mercury.y_velocity = -47.4 * 1000
venus.y_velocity = -35.02 * 1000
earth.y_velocity = 29.783 * 1000
mars.y_velocity = 24.077 * 1000

# new planet if your screen is big enough
jupiter = Planet(5.2 * Planet.AU, 0, 10, ORANGE, 1.898 * 10**27)    
jupiter.y_velocity = -13.1 * 1000&lt;/pre&gt;
  &lt;p id=&quot;ijIv&quot;&gt;Now we&amp;#x27;ll complete update function. Here we count x velocity for planets. You can test and delete starting values for y velocity, you&amp;#x27;ll see something like falling planets on the Sun without moving around it. &lt;/p&gt;
  &lt;pre id=&quot;etMP&quot; data-lang=&quot;python&quot;&gt;def update_position(self, planets): 
    total_force_x = total_force_y = 0 
    for planet in planets: 
        if self == planet: 
            continue  
        fx, fy = self.attraction(planet) 
        total_force_x += fx 
        total_force_y += fy  
    # F = m * a, Newton&amp;#x27;s second law of motion then a = F / m  
    self.x_velocity += total_force_x / self.mass * self.TIMESTEP 
    self.y_velocity += total_force_y / self.mass * self.TIMESTEP
      
    self.x += self.x_velocity * self.TIMESTEP 
    self.y += self.y_velocity * self.TIMESTEP 
    self.orbit.append((self.x, self.y))
    &lt;/pre&gt;
  &lt;p id=&quot;LrTN&quot;&gt;Of course add new function &lt;strong&gt;&lt;em&gt;update_position&lt;/em&gt;&lt;/strong&gt; to the &lt;em&gt;&lt;strong&gt;main &lt;/strong&gt;&lt;/em&gt;function!&lt;/p&gt;
  &lt;pre id=&quot;mMhn&quot;&gt;planet.update_position(planets)&lt;/pre&gt;
  &lt;p id=&quot;TTfg&quot;&gt;Let&amp;#x27;s add some orbits for moving planets. This code should be added to the draw function before drawing circle(planet). &lt;/p&gt;
  &lt;pre id=&quot;LJzB&quot; data-lang=&quot;python&quot;&gt;if len(self.orbit) &amp;gt; 2: 
    updated_points = []
    # we get all points during the movement and with it draw line 
    for point in self.orbit: 
        x, y = point 
        x = x * self.SCALE + WIDTH / 2 
        y = y * self.SCALE + HEIGHT / 2 
        updated_points.append((x, y))  
    # False means it isn&amp;#x27;t enclosed line    
    pygame.draw.lines(win, self.color, False, updated_points, 1)&lt;/pre&gt;
  &lt;p id=&quot;kKb1&quot;&gt;For now you get working simulation that looks pretty cool for me.&lt;/p&gt;
  &lt;figure id=&quot;16s9&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/2c/bf/2cbf538d-0e7d-49e3-bf19-efe8e5687cfb.gif&quot; width=&quot;994&quot; /&gt;
    &lt;figcaption&gt;Working 2D simulation of Solar system&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;7th1&quot;&gt;As always full code can be found at my GitHub: &lt;a href=&quot;https://github.com/rastr-0/solar_system_simulation/blob/main/main.py&quot; target=&quot;_blank&quot;&gt;https://github.com/rastr-0/solar_system_simulation/blob/main/main.py&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;M0V0&quot; data-align=&quot;right&quot;&gt;See ya soon&lt;/p&gt;
  &lt;p id=&quot;eTBS&quot; data-align=&quot;right&quot;&gt;@rastr&lt;/p&gt;

</content></entry><entry><id>rastr_0:binary_trees</id><link rel="alternate" type="text/html" href="https://teletype.in/@rastr_0/binary_trees?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=rastr_0"></link><title>Binary trees</title><published>2022-07-10T21:58:10.816Z</published><updated>2022-07-10T22:18:14.702Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/2a/fe/2afecb27-53eb-4732-972a-a6bb5ff67464.png"></media:thumbnail><category term="algorithms" label="Algorithms"></category><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/6f/b9/6fb96da4-5f6a-47a3-a2db-e1faa6345d91.png&quot;&gt;In this article i'm going to talk about binary trees. Binary tree is a data structure where each node have at most two children(other nodes), usually it's left child and right child</summary><content type="html">
  &lt;p id=&quot;mgXQ&quot;&gt;In this article i&amp;#x27;m going to talk about binary trees. Binary tree is a data structure where each node have at most two children(other nodes), usually it&amp;#x27;s &lt;strong&gt;&lt;em&gt;left child&lt;/em&gt;&lt;/strong&gt; and &lt;em&gt;&lt;strong&gt;right child&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
  &lt;p id=&quot;f5x0&quot;&gt;Sometimes it&amp;#x27;s possible to interpret binary trees as undirected or directed graph, in this case binary tree is &lt;a href=&quot;https://en.wikipedia.org/wiki/Tree_(graph_theory)#Plane_tree&quot; target=&quot;_blank&quot;&gt;ordered&lt;/a&gt; or &lt;a href=&quot;https://en.wikipedia.org/wiki/Tree_(graph_theory)#Rooted_tree&quot; target=&quot;_blank&quot;&gt;rooted&lt;/a&gt; tree. Indeed, that binary tree is a type of &lt;a href=&quot;https://en.wikipedia.org/wiki/M-ary_tree&quot; target=&quot;_blank&quot;&gt;M-ary tree&lt;/a&gt;, where M is 2. &lt;/p&gt;
  &lt;h3 id=&quot;Od12&quot; data-align=&quot;center&quot;&gt;Using of binary trees in programming&lt;/h3&gt;
  &lt;ul id=&quot;4Om6&quot;&gt;
    &lt;li id=&quot;W0GM&quot;&gt;Representation of data with bifurcating structure(rus. разветвляющаяся структура), common use cases: &lt;a href=&quot;https://en.wikipedia.org/wiki/Huffman_coding&quot; target=&quot;_blank&quot;&gt;Huffman coding&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;bHT4&quot;&gt;Using for searching and sorting as they provide hierarchical data storage&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;QkEh&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/6f/b9/6fb96da4-5f6a-47a3-a2db-e1faa6345d91.png&quot; width=&quot;1920&quot; /&gt;
    &lt;figcaption&gt;Example of binary tree, this one is &amp;quot;Huffman tree&amp;quot;, generated fom the exact frequencies of the text &amp;quot;this is an example of a huffman tree&amp;quot; &lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;vkot&quot; data-align=&quot;center&quot;&gt;Types of binary trees&lt;/h3&gt;
  &lt;p id=&quot;3S1v&quot;&gt;I should say that tree terminology is not well-standardized and it could differ, especially if you&amp;#x27;ll open old books&lt;/p&gt;
  &lt;ul id=&quot;KC6y&quot;&gt;
    &lt;li id=&quot;KlZL&quot;&gt;a perfect binary tree: all interior nodes have 2 children and leaves have the same depth. An example of perfect tree is family tree, becuase all people have two parents.&lt;/li&gt;
    &lt;li id=&quot;dVB5&quot;&gt;a degenerate binary tree: every node has only one chlid, so tree will behave as linked list&lt;/li&gt;
    &lt;li id=&quot;5IRD&quot;&gt;a full binary tree: type of binary tree in which every node has 0 or 2 children. A full binary tree also is: &lt;/li&gt;
  &lt;/ul&gt;
  &lt;section style=&quot;background-color:hsl(hsl(263, 48%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;ol id=&quot;ivHJ&quot;&gt;
      &lt;li id=&quot;eviR&quot;&gt;single vertex &lt;/li&gt;
      &lt;li id=&quot;WQVP&quot;&gt;tree whose root subtrees are full bynary trees&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/section&gt;
  &lt;ul id=&quot;RR1F&quot;&gt;
    &lt;li id=&quot;PVNb&quot;&gt;a complete binary tree: binary tree, in which level, except lpossibly ast, is completely filled and all nodes as far left as possible&lt;/li&gt;
    &lt;li id=&quot;dX0q&quot;&gt;a balanced binary tree: binary tree in which left and right subtrees of every nodes differ in height no more than 1&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;8N6F&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/62/ca/62cae0b3-a83f-47fe-ae71-e7abf333b081.png&quot; width=&quot;1400&quot; /&gt;
    &lt;figcaption&gt;Illustration of binary trees&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;9ZMI&quot; data-align=&quot;center&quot;&gt;Properties of binary trees&lt;/h3&gt;
  &lt;p id=&quot;bSVR&quot; data-align=&quot;center&quot;&gt;&lt;strong&gt;Some obvious facts&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;xFsv&quot;&gt;
    &lt;li id=&quot;XX6S&quot;&gt;the minimum number of nodes at height H = H + 1&lt;/li&gt;
    &lt;li id=&quot;69DB&quot;&gt;the maximum number of nodes at height H = 2^H - 1&lt;/li&gt;
    &lt;li id=&quot;ZljL&quot;&gt;the maximum number of nodes at any level(n) = 2^n&lt;/li&gt;
    &lt;li id=&quot;9FS7&quot;&gt;minimum possible hieghts or levels = log2(n + 1)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;mwk2&quot;&gt;if you want to see other properties you&amp;#x27;re free to visit &lt;a href=&quot;https://en.wikipedia.org/wiki/Binary_tree#:~:text=In%20computer%20science%2C%20a%20binary,child%20and%20the%20right%20child.&quot; target=&quot;_blank&quot;&gt;wiki&lt;/a&gt;&lt;/p&gt;
  &lt;h3 id=&quot;yNn5&quot; data-align=&quot;center&quot;&gt;Methods for storing binary trees&lt;/h3&gt;
  &lt;ul id=&quot;G2q6&quot;&gt;
    &lt;li id=&quot;epgc&quot;&gt;using of references and nodes&lt;/li&gt;
    &lt;li id=&quot;slXg&quot;&gt;using of arrays(this one benefits from more compact storage and better locality to references)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;cAy3&quot; data-align=&quot;center&quot;&gt;Implementation&lt;/h3&gt;
  &lt;p id=&quot;plm8&quot;&gt;I&amp;#x27;ll implement solution in c++. I&amp;#x27;ve done Search Binary tree, it&amp;#x27;s a little bit complicated, because we need to add elements in tree &lt;a href=&quot;https://www.geeksforgeeks.org/binary-search-tree-data-structure/&quot; target=&quot;_blank&quot;&gt;according to certain rules&lt;/a&gt;. &lt;/p&gt;
  &lt;h3 id=&quot;r3af&quot; data-align=&quot;center&quot;&gt;C++ solution of binary search tree&lt;/h3&gt;
  &lt;p id=&quot;hs9y&quot;&gt;Creating structure for node, it&amp;#x27;s basically data, pointer to next left node and next right node. Also here is two constructions. &lt;/p&gt;
  &lt;pre id=&quot;bZ9K&quot; data-lang=&quot;cpp&quot;&gt;struct Node { 
    int data; 
    Node* left; 
    Node* right; 
    Node(int data) { 
        this-&amp;gt;data = data; 
        left = nullptr; 
        right = nullptr; 
    }
    Node() { 
        data = 0; 
        left = nullptr; 
        right = nullptr; 
    }
};&lt;/pre&gt;
  &lt;p id=&quot;YXoG&quot;&gt;This is class Binary_tree, which defines some functions for adding elements, printing in different order and destroing tree.&lt;/p&gt;
  &lt;pre id=&quot;CrF1&quot; data-lang=&quot;cpp&quot;&gt;class Binary_tree 
{
private: 
    Node* root; 
    void destroy(Node* leaf); 
    void insert(int key, Node* leaf); 
    void inorder_print(Node* leaf); 
    void preorder_print(Node* leaf); 
    void postorder_print(Node* leaf); 
    Node* search(int key, Node* leaf);
public: 
    Binary_tree(); 
    void insert(int key); 
    void destroy(); 
    void inorder_print(); 
    void preorder_print(); 
    void postorder_print(); 
    Node* search(int key);};&lt;/pre&gt;
  &lt;p id=&quot;i2KB&quot;&gt;Let&amp;#x27;s start from insert function. Code is well-commented, so you don&amp;#x27;t actually need my comments&lt;/p&gt;
  &lt;pre id=&quot;JgCz&quot; data-lang=&quot;cpp&quot;&gt;void Binary_tree::insert(int key, Node* leaf) {
    if (key &amp;lt; leaf-&amp;gt;data) { 
        // if leaf-&amp;gt;right isn&amp;#x27;t a leaf, than go to the next and check 
        if (leaf-&amp;gt;left != nullptr)
            insert(key, leaf-&amp;gt;left); 
        // if it is a leaf, than create a new object 
        // and initialize data with key 
        else { 
            leaf-&amp;gt;left = new Node(); 
            leaf-&amp;gt;left-&amp;gt;data = key; 
        } 
    } 
    else if (key &amp;gt;= leaf-&amp;gt;data) { 
        // if leaf-&amp;gt;right isn&amp;#x27;t a leaf, than go to the next and check 
        if (leaf-&amp;gt;right != nullptr)
            insert(key, leaf-&amp;gt;right); 
        // if it is a leaf, than create a new object 
        // and initialize data with key 
        else { 
            leaf-&amp;gt;right = new Node(); 
            leaf-&amp;gt;right-&amp;gt;data = key; 
        } 
    }
}&lt;/pre&gt;
  &lt;p id=&quot;BvEi&quot;&gt;Next function is destroy. It&amp;#x27;s pretty simple. &lt;/p&gt;
  &lt;pre id=&quot;C7lX&quot; data-lang=&quot;cpp&quot;&gt;void Binary_tree::destroy(Node* leaf) {
    if (leaf != nullptr) { 
        destroy(leaf-&amp;gt;left); 
        destroy(leaf-&amp;gt;right); 
        delete leaf; 
    }
}&lt;/pre&gt;
  &lt;p id=&quot;uaPw&quot;&gt;The last complicated function is search function.&lt;/p&gt;
  &lt;pre id=&quot;XBxY&quot; data-lang=&quot;cpp&quot;&gt;Node* Binary_tree::search(int key, Node* leaf) { 
    if (leaf != nullptr) { 
        if (leaf-&amp;gt;data == key) 
            return leaf; 
        else if (key &amp;gt; leaf-&amp;gt;data) 
            return search(key, leaf-&amp;gt;right); 
        else 
            return search(key, leaf-&amp;gt;left); 
    } 
    else 
        return nullptr; // there are no elements in Binary_tree
}&lt;/pre&gt;
  &lt;p id=&quot;VqLg&quot;&gt;Next important thing is different types of traversing tree, it means visiting and outputing all values of each node in particular order.  &lt;/p&gt;
  &lt;p id=&quot;8r0m&quot;&gt;Each of traversing methods have a particular order they follow  &lt;/p&gt;
  &lt;ul id=&quot;ip1W&quot;&gt;
    &lt;li id=&quot;4OUh&quot;&gt;For &lt;strong&gt;Inorder&lt;/strong&gt;, you traverse from the &lt;strong&gt;left &lt;/strong&gt;subtree to the &lt;strong&gt;root&lt;/strong&gt; then to the &lt;strong&gt;right&lt;/strong&gt; subtree.&lt;/li&gt;
    &lt;li id=&quot;n4WJ&quot;&gt;For &lt;strong&gt;Preorder&lt;/strong&gt;, you traverse from the &lt;strong&gt;root &lt;/strong&gt;to the &lt;strong&gt;left &lt;/strong&gt;subtree then to the &lt;strong&gt;right&lt;/strong&gt; subtree.&lt;/li&gt;
    &lt;li id=&quot;Cxis&quot;&gt;For &lt;strong&gt;Post order&lt;/strong&gt;, you traverse from the &lt;strong&gt;left &lt;/strong&gt;subtree to the &lt;strong&gt;right &lt;/strong&gt;subtree then to the &lt;strong&gt;root&lt;/strong&gt;.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;V2TJ&quot;&gt;Let&amp;#x27;s have a look at code.&lt;/p&gt;
  &lt;pre id=&quot;CxfO&quot; data-lang=&quot;cpp&quot;&gt;// left - &amp;gt; root - &amp;gt; right
void Binary_tree::inorder_print(Node* leaf) { 
    if (leaf != nullptr) { 
        inorder_print(leaf-&amp;gt;left); 
        std::cout &amp;lt;&amp;lt; leaf-&amp;gt;data &amp;lt;&amp;lt; &amp;quot; &amp;quot;; 
        inorder_print(leaf-&amp;gt;right); 
    }
}&lt;/pre&gt;
  &lt;pre id=&quot;Hp1W&quot; data-lang=&quot;cpp&quot;&gt;// root - &amp;gt; left - &amp;gt; right
void Binary_tree::preorder_print(Node* leaf) { 
    if (leaf != nullptr) { 
        std::cout &amp;lt;&amp;lt; leaf-&amp;gt;data &amp;lt;&amp;lt; &amp;quot; &amp;quot;; 
        inorder_print(leaf-&amp;gt;left); 
        inorder_print(leaf-&amp;gt;right); 
    }
}&lt;/pre&gt;
  &lt;pre id=&quot;2J4R&quot; data-lang=&quot;cpp&quot;&gt;// left - &amp;gt; right - &amp;gt; root
void Binary_tree::postorder_print(Node* leaf) { 
    if (leaf != nullptr) { 
        inorder_print(leaf-&amp;gt;left); 
        inorder_print(leaf-&amp;gt;right); 
        std::cout &amp;lt;&amp;lt; leaf-&amp;gt;data; 
    }
}&lt;/pre&gt;
  &lt;p id=&quot;UU7R&quot;&gt;I won&amp;#x27;t comment my public methods, it&amp;#x27;s done for encapsulation and mostly they just call private functions. &lt;/p&gt;
  &lt;p id=&quot;RNDH&quot;&gt;Full code at my GitHub profile: &lt;a href=&quot;https://github.com/rastr-0/Simple_algorithms/blob/master/binary_tree/binary_tree.cpp&quot; target=&quot;_blank&quot;&gt;https://github.com/rastr-0/Simple_algorithms/blob/master/binary_tree/binary_tree.cpp&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;6mYX&quot; data-align=&quot;right&quot;&gt;See ya soon&lt;/p&gt;
  &lt;p id=&quot;aWnE&quot; data-align=&quot;right&quot;&gt;@rastr&lt;/p&gt;

</content></entry><entry><id>rastr_0:solving_sudoku_by_rastr</id><link rel="alternate" type="text/html" href="https://teletype.in/@rastr_0/solving_sudoku_by_rastr?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=rastr_0"></link><title>Solving easy sudoku(backtracking)</title><published>2022-07-07T14:21:13.812Z</published><updated>2022-07-10T22:13:55.421Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/9b/90/9b90d062-68ee-4055-a74f-5f56c7f6e6ed.png"></media:thumbnail><category term="algorithms" label="Algorithms"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/b6/00/b600b859-9fe1-4349-813b-c49d6d01cae5.gif&quot;&gt;In this article I’d like to consider backtracking technique. Backtracking is a type of BFS (Brute-force-search) algorithm. Backtracking is DFS(depth first search), because it’ll completely go through one branch before moving to the next. </summary><content type="html">
  &lt;p id=&quot;EqPs&quot;&gt;In this article I’d like to consider backtracking technique. Backtracking is a type of BFS (Brute-force-search) algorithm. Backtracking is &lt;a href=&quot;https://github.com/rastr-0/Simple_algorithms/blob/master/dfs/dfs_search.cpp&quot; target=&quot;_blank&quot;&gt;DFS&lt;/a&gt;(depth first search), because it’ll completely go through one branch before moving to the next. &lt;/p&gt;
  &lt;h3 id=&quot;V1an&quot; data-align=&quot;center&quot;&gt;Short description of the algorithm&lt;/h3&gt;
  &lt;p id=&quot;6nnq&quot;&gt;Briefly, the program would put 1 in the first cell and check if it’s allowed(checking row, column and box). If it is, go to the next cell, put 1 and check. If it finds out it’s invalid, then increase the number and check again. If a cell is discovered where none of the 9 digits are allowed, then leaves that cell blank and moves back to the previous cell, the number in that cell incremented by one.&lt;/p&gt;
  &lt;figure id=&quot;RYfR&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b6/00/b600b859-9fe1-4349-813b-c49d6d01cae5.gif&quot; width=&quot;297&quot; /&gt;
    &lt;figcaption&gt;illustration of solving sudoku with backtracking metho&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;WiGV&quot; data-align=&quot;center&quot;&gt;Advantages of this method are&lt;/h3&gt;
  &lt;ul id=&quot;iHNu&quot;&gt;
    &lt;li id=&quot;WVwu&quot;&gt;A solution is guaranteed(As long as sudoku is valid)&lt;/li&gt;
    &lt;li id=&quot;SLru&quot;&gt;Quite simple code in comparison with another methods &lt;/li&gt;
    &lt;li id=&quot;dUKA&quot;&gt;Solving time is mostly unrelated to “degree of difficulty” of sudoku&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;2Lxp&quot;&gt;The main disadvantage is that solving time might be so slow compared to algorithms modeled after deductive methods. Also sudoku can be designed against backtracking method.&lt;/p&gt;
  &lt;h2 id=&quot;8zsx&quot; data-align=&quot;center&quot;&gt;Solution&lt;/h2&gt;
  &lt;p id=&quot;XB5P&quot;&gt;I’m going to use python for solving it but solutions can be easily implemented in another language. First of all, I’d like to create three checking functions: used_row, used_col, used_box. Used_row function just checks if we find the same number in row. Here comes used_row function.&lt;/p&gt;
  &lt;pre id=&quot;OGfL&quot; data-lang=&quot;python&quot;&gt;def used_row(puzzle, row, num):    
    for i in range(9):        
        if puzzle[row][i] == num:            
            return True    
    return False        &lt;/pre&gt;
  &lt;p id=&quot;hfB6&quot;&gt;Used_col checks if we find the same number in col. That’s pretty simple.&lt;/p&gt;
  &lt;pre id=&quot;ZSTM&quot; data-lang=&quot;python&quot;&gt;def used_col(puzzle, row, num):
    for i in range(9):
        if puzzle[i][col] == num:
            return True
    return False&lt;/pre&gt;
  &lt;p id=&quot;AIv7&quot;&gt;Used_box checks if we find the same number in box 3 x 3. I think you shouldn&amp;#x27;t struggle with understanding it.&lt;/p&gt;
  &lt;pre id=&quot;XOTS&quot; data-lang=&quot;python&quot;&gt;def used_box(puzzle, row, col, num):    
    for i in range(3):        
        for j in range(3):            
            if puzzle[i + row][j + col] == num:                
                return True    
    return False&lt;/pre&gt;
  &lt;p id=&quot;oxwl&quot;&gt;Next function will be is_safe. It’s gonna check if one of these functions return true.&lt;/p&gt;
  &lt;pre id=&quot;39XK&quot; data-lang=&quot;python&quot;&gt;def is_safe(puzzle, row, col, num):    
    return not used_row(puzzle, row, num) and 
        not used_col(puzzle, col, num) and 
        not used_box(puzzle, row - row % 3, col - col % 3, num)&lt;/pre&gt;
  &lt;p id=&quot;Gsnq&quot;&gt;The reason why I pass this kind of arguments (row - row % 3 and col - col % 3) that&amp;#x27;s becuase we need to check if we find number in square 3x3, that&amp;#x27;s the easiest way to do it. &lt;/p&gt;
  &lt;p id=&quot;51hs&quot;&gt;Next function is find_empty_cell. l_vars contain i and j indexes; in other words these list stores index of empty cell.&lt;/p&gt;
  &lt;pre id=&quot;2l5b&quot; data-lang=&quot;python&quot;&gt;def find_empty_cell(puzzle, l_vars):    
    for i in range(9):        
        for j in range(9):            
            if puzzle[i][j] == 0:                
                l_vars[0], l_vars[1] = i, j                
                return True    
     return False&lt;/pre&gt;
  &lt;p id=&quot;plEM&quot;&gt;Last function is solve_sudoku. It is a recursive function, which returns False if sudoku is unsolvable&lt;/p&gt;
  &lt;pre id=&quot;yva7&quot; data-lang=&quot;python&quot;&gt;def solve_sudoku(puzzle):    
    l_vars = [0, 0]    
    if not find_empty_cell(puzzle, l_vars):        
        return True            
     
     row, col = l_vars[0], l_vars[1]
             
     for num in range(1, 10):        
         if is_safe(puzzle, row, col, num):            
             puzzle[row][col] = num            
             if solve_sudoku(puzzle):                
                 return True            
         puzzle[row][col] = 0                
     return False&lt;/pre&gt;
  &lt;p id=&quot;jMb0&quot;&gt;So, that&amp;#x27;s it. If you still got problems with implementing it you can go thorugh my code.&lt;/p&gt;
  &lt;p id=&quot;lZyr&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;eau4&quot;&gt;Link to GitHub repo: &lt;a href=&quot;https://github.com/rastr-0/teletype_source_files&quot; target=&quot;_blank&quot;&gt;https://github.com/rastr-0/teletype_source_files&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;XFNc&quot; data-align=&quot;right&quot;&gt;See ya soon &lt;/p&gt;
  &lt;p id=&quot;Pgat&quot; data-align=&quot;right&quot;&gt;@rastr &lt;/p&gt;

</content></entry></feed>