• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

How to check where x falls?

Engaged ,
Oct 30, 2021 Oct 30, 2021

Copy link to clipboard

Copied

Hi,

 

How to check where x falls?

 

check(116);

function check(x) {
	return 1+(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643);
}

 

Regards,

Sumit

-Sumit
TOPICS
Scripting

Views

1.4K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 4 Correct answers

Community Expert , Nov 22, 2021 Nov 22, 2021

Hi @SumitKumar,

I looked into the code and as @Peter Kahrel mentioneed the return value for 

PAGE_TO_SECTION(320) is 11575 and not 75 as you mentioned in the other post. Now as regards to what the following code snippet does
const RANGES = [41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643];
const PAGE_TO_SECTION = (function(/*uint[]&*/a,  n,s,i)
// -------------------------------------
// Return the func that converts a page number into a
// section number (1..N) depending o
...

Votes

Translate

Translate
Participant , Nov 23, 2021 Nov 23, 2021

If we need more than 12k checks, then no optimization is required, but I think we can speed up the script execution.
For this we need to create an object that already has a chapter number for each page.

 

#targetengine 'check chapter'

var LIST_OF_PAGES = {}
main()

function main(){

	const RANGES = [41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643]

	function create(from,to,chapter){
		for(var i = from; i < to; i++){
			LIST_OF_PAGES[i] = chapter
		}
	}
	
	for(var i = 0; i < R
...

Votes

Translate

Translate
Participant , Nov 23, 2021 Nov 23, 2021

Yesterday I had a lot of work, I suspected that I was wrong, but I could not understand what, today I understood))
Here one script is enough, for this we need to check the variable LIST_OF_PAGES

 

#targetengine 'check chapter'

if(typeof LIST_OF_PAGES == 'undefined'){
	var LIST_OF_PAGES = {}
	main()
	get()
}
else{get()}

function main(){

	const RANGES = [41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643]

	function create(from,to,chapter){
		for(var i = from; i < to; i++){
			L
...

Votes

Translate

Translate
Guide , Nov 25, 2021 Nov 25, 2021

Hi @SumitKumar 

 

No procedural approach can beat @SychevKA's method, since it is based on a pre-processed, full mapping of page numbers into section indices. Its object `LIST_OF_PAGES` already contains the set of all possible page numbers, so that `LIST_OF_PAGES[anyPage]` instantly returns the corresponding section number. (By instantly, I mean something like 2-3 µs on any decent system.)

 

Hence this is without doubt the most efficient approach. Even a highly fine-tuned binary algorithm won't run

...

Votes

Translate

Translate
Participant ,
Nov 23, 2021 Nov 23, 2021

Copy link to clipboard

Copied

Yesterday I had a lot of work, I suspected that I was wrong, but I could not understand what, today I understood))
Here one script is enough, for this we need to check the variable LIST_OF_PAGES

 

#targetengine 'check chapter'

if(typeof LIST_OF_PAGES == 'undefined'){
	var LIST_OF_PAGES = {}
	main()
	get()
}
else{get()}

function main(){

	const RANGES = [41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643]

	function create(from,to,chapter){
		for(var i = from; i < to; i++){
			LIST_OF_PAGES[i] = chapter
		}
	}
	
	for(var i = 0; i < RANGES.length; i++){
		var chapter = 'chapter '+(i+1)
		create(RANGES[i],RANGES[i+1],chapter)
	}

	if(RANGES[0] > 1){create(0,RANGES[0],0)}
	LIST_OF_PAGES['last'] = chapter
}

function get(){
	function get_rand(min,max){
		return Math.floor(Math.random()*(max-min))+min
	}

	var check = {}
	for(var i = 0; i < 10; i++){
		var page = get_rand(1,700)
	
		// get a chapter without compare
		var chapter = LIST_OF_PAGES[page]
		if(typeof chapter == 'undefined'){check[page] = LIST_OF_PAGES['last']}
		else{check[page] = chapter}
	}

	var show = []
	for(var k in check){
		show.push('\n'+k+'->'+check[k])
	}

	alert(show)
}

 

> map multiple pages with same value

This way we load the processor more, my way is to load more RAM. And I think my method will run faster.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

Thank you SychevKA.

-Sumit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

Nice one, Sychev. Comparing your function is a factor 10 faster than Marc's and mine.

P.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

All brilliant suggestions here. That is why I love this community 🙂

-Manan

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 23, 2021 Nov 23, 2021

Copy link to clipboard

Copied

Great, Thank you Manan!

Regards,

-Sumit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 23, 2021 Nov 23, 2021

Copy link to clipboard

Copied

Thank you Manan, this is what I was searching.

You are supurb, I would like to work with you in future if any opportunities.

 

I looked into the code and as @Peter Kahrel mentioneed the return value for 

PAGE_TO_SECTION(320) is 11575 and not 75 as you mentioned in the other post.

 

Yes PAGE_TO_SECTION(320) return 11575 thats my fault, but if you see Marc post he used substr that's why getting 75. 

 

__(HREF_PATTERN,('0'+P2S(p)).substr(-2),p)

 

 

Also, I have one question which approach is better?

Marc

===============

 

const RANGES = [41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643];
const PAGE_TO_SECTION = (function(/*uint[]&*/a,  n,s,i)
// -------------------------------------
// Return the func that converts a page number into a
// section number (1..N) depending on RANGES.
// E.g. PAGE_TO_SECTION(320) => 9
{
    for( n=a.length, s='1', i=-1 ; ++i < n ; s+='+(x>'+a[i]+')' );
    return Function('x', 'return '+s);
})(RANGES);

 

SychevKA 

===============

 

var LIST_OF_PAGES = {}
const RANGES = [41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643]
function create(from,to,chapter){
		for(var i = from; i < to; i++){
			LIST_OF_PAGES[i] = chapter
		}
	}
	
	for(var i = 0; i < RANGES.length; i++){
		var chapter = 'chapter '+(i+1)
		create(RANGES[i],RANGES[i+1],chapter)
	}

 

 

Regards,

Sumit

-Sumit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Nov 25, 2021 Nov 25, 2021

Copy link to clipboard

Copied

Hi @SumitKumar 

 

No procedural approach can beat @SychevKA's method, since it is based on a pre-processed, full mapping of page numbers into section indices. Its object `LIST_OF_PAGES` already contains the set of all possible page numbers, so that `LIST_OF_PAGES[anyPage]` instantly returns the corresponding section number. (By instantly, I mean something like 2-3 µs on any decent system.)

 

Hence this is without doubt the most efficient approach. Even a highly fine-tuned binary algorithm won't run faster, noting that in ExtendScript the access to object members remains ultra-fast no matter the number of registered keys.

 

However, as Sychev noted, execution time is saved by consuming more memory. Should the document or book contain 5,000 pages, the map LIST_OF_PAGES will have to address 5,000 key/value pairs, with a lot of redundancy like { … "2492"=>"chapter 8", "2493"=>"chapter 8", "2494"=>"chapter 8" … }.

 

In conclusion, this is the fastest approach but not the most memory-optimal. Some improvements are possible without reducing significantly the speed of execution.

For example, instead of creating an object of 5,000 members, you may compact the whole data structure in a UTF16 string of 5,000 characters. It still sounds huge but you can be sure that a single 5K string is much lighter than a Object reference mapping 5K keys (=strings) to 5K values (=strings).

 

I made some tests based on this idea and the function responds in 1 or 2 microseconds longer than the map. That's a middle ground between extreme performance and saving memory.

 

Edit: better code display

 

 

const PageToRange = function(/*uint>0*/p,  q)
//----------------------------------
// Returns the 1-based range index containing page number `p`.
// (The last range supports any `p` beyond the maximum.)
// [REM] Use PageToRange.setup() to initialize the ranges.
// ---
// => uint [1 for 1st range, 2 for 2nd range...]  |  false [INVALID p]
{
   return p > 0 && ((q=callee.Q).charCodeAt(-1+p)||q.charCodeAt(-1+q.length));
};

PageToRange.setup = function(/*uint[]*/a,  r,z,p,i,t)
//----------------------------------
// Register an ordered list of page numbers (0 < a[i] < a[i+1].)
// => undef
{
   const CHR = String.fromCharCode;
   for
   (
      r=[], p=z=0, i=-1 ;
      ++i < a.length ;
      p < (t=a[i])
      && ( r[r.length]=Array(1+t-p).join(CHR(++z)), p=t )
   );
   this.Q = r.join('');
}

//----------------------------------
// TEST
//----------------------------------

// `41` means "pages 1 to 41", `73` means "pages 42 to 73", etc.
const RANGES = [41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643];

// Init. (required once.)
PageToRange.setup(RANGES);

var i,arr,dt,msg;

// Loading N random numbers ranging in [1..800]
const N = 10000;
arr = (function(i,K,RND,r){ for(r=[];i--;r.push(1+~~(K*RND()))); return r;})(N,800,Math.random);

// Benchmark.
for
(
   dt=0, i=arr.length ; i-- ;
   arr[i]=[$.hiresTimer,PageToRange(arr[i]),dt+=$.hiresTimer][1]
);

msg = ("Total processing time: " + ~~(dt/1e3) + "ms (" + N + " numbers)\r")
   + ("Average `PageToRange` time: " + ~~(dt/N) + "µs\r\r")
   + ("First results:\r" + arr.splice(0,200).join() + '...');

alert( msg );

 

 

 

MarcAutret_0-1637858004172.png

 

Best,

Marc

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 25, 2021 Nov 25, 2021

Copy link to clipboard

Copied

LATEST

Thank you @Marc Autret ,

This approach would save memory as well as execution time.

 

Regards,

-Sumit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines